Форум dkLab и Denwer
Здесь общаются Web-разработчики.
Генеральный спонсор:
Хостинг «Джино»

array_multisort_key: сортировка двумерного ассоц. массива, по структуре похожего на таблицу БД (Rin)
Author Message
Rin
Участник форума



Joined: 01 Jun 2005
Posts: 515
Карма: 185
   поощрить/наказать

Location: Москва

PostPosted: Thu Jun 23, 2005 1:13 pm (написано за 4 минуты 47 секунд)
   Post subject: array_multisort_key: сортировка двумерного ассоц. массива, по структуре похожего на таблицу БД
Reply with quote

Code (php): скопировать код в буфер обмена
<?php

/*
function array_multisort_key($array, $key, $type = SORT_ASC, $cmp_func = 'strcmp')
{
    $GLOBALS['ARRAY_MULTISORT_KEY_SORT_KEY']  = $key;
    usort (www.php.net/usort)($array, create_function (www.php.net/create_function)('$a, $b', '$k = &$GLOBALS["ARRAY_MULTISORT_KEY_SORT_KEY"];
                                             return '
. $cmp_func . '($a[$k], $b[$k]) * ' . ($type == SORT_ASC ? 1 : -1) . ';'));
    return $array;
}

?>
CHANGELOG:

v1.0.2 /2006-03-01/
  * добавлен 4-й параметр для выбора функции сравнения строк
  * немного оптимизирован код
  

TEST CASE:
Code (php): скопировать код в буфер обмена
  error_reporting (www.php.net/error_reporting)(E_ALL /*& ~E_NOTICE & ~E_USER_NOTICE*/);
  $a = array (www.php.net/array)(
      array (www.php.net/array)('id' => 4, 'name' => 'Sveta', 'sex' => 'female'),
      array (www.php.net/array)('id' => 1, 'name' => 'Rin',   'sex' => 'male'),
      array (www.php.net/array)('id' => 3, 'name' => 'Vika''sex' => 'female'),
      array (www.php.net/array)('id' => 2, 'name' => 'Igor''sex' => 'male'),
  );

  echo (www.php.net/echo) '<pre>';
  print_r (www.php.net/print_r)(array_multisort_key($a, 'id', SORT_ASC));
  print_r (www.php.net/print_r)(array_multisort_key($a, 'id', SORT_DESC));
  print_r (www.php.net/print_r)(array_multisort_key($a, 'name', SORT_ASC));
  echo (www.php.net/echo) '</pre>';
?>


Last edited by Rin on Wed Mar 01, 2006 11:31 am; edited 2 times in total
Back to top
View user's profile Send private message Send e-mail
chin
Участник форума



Joined: 23 Feb 2005
Posts: 312
Карма: 26
   поощрить/наказать

Location: Украина, Киев

PostPosted: Wed Mar 01, 2006 2:42 am (спустя 8 месяцев 5 дней 13 часов 28 минут; написано за 9 минут 17 секунд)
   Post subject:
Reply with quote

Я вот тут бродил по форуму и наткнулся на это решение. И тут понял, что сам сегодня сталкивался с проблемой отсортировать двумерный массив по ключу. По сему, написал свою функцию:
Code (php): скопировать код в буфер обмена
function array_order($array,$key,$type=SORT_ASC)
{
    if(!is_array (www.php.net/is_array)($array)) return;
    $ASC = ( $type === SORT_ASC );
    $elements = count (www.php.net/count)($array)-1;
    for($i = 0; $i < $elements; $i++) {
        for($k = $elements; $k > $i ; $k--) {
            if($ASC ? $array[$k][$key] < $array[$k-1][$key] : $array[$k][$key] > $array[$k-1][$key]) {
                $buf = $array[$k-1]; $array[$k-1] = $array[$k]; $array[$k] = $buf;
            }
        }
    }
    return $array;
}
По сути, работает ТОЧНО так-же, как и приведенная выше. Я уже думал, мол: "Ну вот, опять изобрел велосипед". Запихнул функцию Rin-а себе в код, проверил.. И тут решил сравнить скорость работы. После некоторого теста:
Code (php): скопировать код в буфер обмена
$a = array (www.php.net/array)(
      array (www.php.net/array)('id' => 4, 'name' => 'Sveta', 'sex' => 'female'),
      array (www.php.net/array)('id' => 1, 'name' => 'Rin',   'sex' => 'male'),
      array (www.php.net/array)('id' => 3, 'name' => 'Vika''sex' => 'female'),
      array (www.php.net/array)('id' => 2, 'name' => 'Igor''sex' => 'male'),
  );
 
  $multisort_time=array_sum (www.php.net/array_sum)(explode (www.php.net/explode)(' ',microtime (www.php.net/microtime)()));
  for($i = 0; $i < 100; $i++) array_multisort_key($a,'id',SORT_ASC);
  $multisort_time=round (www.php.net/round)(array_sum (www.php.net/array_sum)(explode (www.php.net/explode)(' ',microtime (www.php.net/microtime)()))-$multisort_time,4);
 
  $array_order_time=array_sum (www.php.net/array_sum)(explode (www.php.net/explode)(' ',microtime (www.php.net/microtime)()));
  for($i = 0; $i < 100; $i++) array_order($a,'id',SORT_ASC);
  $array_order_time=round (www.php.net/round)(array_sum (www.php.net/array_sum)(explode (www.php.net/explode)(' ',microtime (www.php.net/microtime)()))-$array_order_time,4);
 
  echo (www.php.net/echo) "multisort time: $multisort_time<br />";
  echo (www.php.net/echo) "array_order time: $array_order_time";
  // Вывод:
  // multisort time: 0.0322
  // array_order time: 0.0135
 
Я понял, что моя функция работает в два с половиной раза быстрее. Осталось только выяснить, правильно ли она работает? Я проверял, вродебы выдает результаты идентичные первой.
Кстати, а есть ли смысл копать в этом направлении дальше и, скажем, написать функцию, которая будет сортировать по нескольким ключам? Типа ORDER BY position ASC, time DESC?
Back to top
View user's profile Send private message Send e-mail
Rin
Участник форума



Joined: 01 Jun 2005
Posts: 515
Карма: 185
   поощрить/наказать

Location: Москва

PostPosted: Wed Mar 01, 2006 11:37 am (спустя 8 часов 55 минут; написано за 2 минуты 38 секунд)
   Post subject:
Reply with quote

А вы пробовали увеличить кол-во элементов хотябы до 150 и отсортировать по ключу "name"?
Ваша функция работает в 3 раза медленнее, а на 300 элементов уже в 7 раз медленнее... :)
Back to top
View user's profile Send private message Send e-mail
chin
Участник форума



Joined: 23 Feb 2005
Posts: 312
Карма: 26
   поощрить/наказать

Location: Украина, Киев

PostPosted: Wed Mar 01, 2006 7:25 pm (спустя 7 часов 47 минут; написано за 49 секунд)
   Post subject:
Reply with quote

ух, вот этого не тестировал (:
ну тут несомненно - встроенные функции будут работать бысрее.
я вижу, Вы чуть чуть изменили свой код... usort --> strcmp?
Back to top
View user's profile Send private message Send e-mail
Display posts from previous:   
Post new topic   Reply to topic All times are GMT + 3 Hours
Page 1 of 1    Email to a Friend.
You cannot post new topics in this forum. You cannot reply to topics in this forum. You cannot edit your posts in this forum. You cannot delete your posts in this forum. You cannot vote in polls in this forum. You cannot attach files in this forum. You can download files in this forum.
XML