PHP сортирует массив по двум значениям поля - PullRequest
61 голосов
/ 03 января 2011

У меня есть такой массив

Array (
 [0] => Array( "destination" => "Sydney",
               "airlines" => "airline_1",
               "one_way_fare" => 100,
               "return_fare => 300
       ),
 [2] => Array( "destination" => "Sydney",
               "airlines" => "airline_2",
               "one_way_fare" => 150,
               "return_fare => 350
       ),
 [3] => Array( "destination" => "Sydney",
               "airlines" => "airline_3",
               "one_way_fare" => 180,
               "return_fare => 380
       )
)

Как мне отсортировать значение по return_fare asc, one_way_fare asc?

Я пытался array_multisort () , но в итоге я перепутал данные ...

asort работает только для одномерного массива, мне нужно отсортировать по двум или более значениям, как я могу добиться этого, как в SQL, упорядочить по field1 asc, field2 asc?

Ответы [ 6 ]

95 голосов
/ 03 января 2011

array_multisort() - правильная функция, вы, должно быть, как-то напутали:

// Obtain a list of columns
foreach ($data as $key => $row) {
    $return_fare[$key]  = $row['return_fare'];
    $one_way_fare[$key] = $row['one_way_fare'];
}

// Sort the data with volume descending, edition ascending
array_multisort($return_fare, SORT_ASC, $one_way_fare, SORT_ASC, $data);

Если вы посмотрите на комментарии на странице руководства PHP для array_multisort(),Вы можете найти очень полезную функцию array_orderby(), которая позволяет сократить вышеупомянутое до следующего:

$sorted = array_orderby($data, 'return_fare', SORT_ASC, 'one_way_fare', SORT_ASC);

Чтобы избежать зацикливания, используйте array_column() (по состоянию на PHP 5.5.0):

array_multisort(array_column($data, 'return_fare'),  SORT_ASC,
                array_column($data, 'one_way_fare'), SORT_ASC,
                $data);
33 голосов
/ 03 января 2011

В дополнение к array_multisort(), который требует от вас сначала построения массивов столбцов, есть также usort(), который не требует такой вещи.

usort($data, function($a, $b) { 
    $rdiff = $a['return_fare'] - $b['return_fare'];
    if ($rdiff) return $rdiff; 
    return $a['one_way_fare'] - $b['one_way_fare']; 
}); // anonymous function requires PHP 5.3 - use "normal" function earlier
9 голосов
/ 29 июля 2015

Или вы можете использовать uasort следующим образом

uasort($arr, function($a,$b){
    $c = $a['return_fare'] - $b['return_fare'];
    $c .= $a['one_way_fare'] - $b['one_way_fare'];
    return $c;
});

Fiddle

5 голосов
/ 08 декабря 2017

Другой пример использования оператора космического корабля.

usort($data, function($a, $b) { 
    return $a['return_fare'] <=> $b['return_fare'] ?: $a['one_way_fare'] <=> $b['one_way_fare'] 
});
4 голосов
/ 09 декабря 2018

Я отвечу на это так: обобщенно , независимо от того, сколько предметов вы хотите отсортировать!

Сортировка по return_fare, затем one_way_fare:

usort($data, function($a, $b) {
   if ($a['return_fare'] != $b['return_fare']) {
      return $a['return_fare'] <=> $b['return_fare'];
   }

   return $a['one_way_fare'] <=> $b['one_way_fare'];
});

Сортировка по return_fare, затем one_way_fare, затем destination:

usort($data, function($a, $b) {
   if ($a['return_fare'] != $b['return_fare']) {
      return $a['return_fare'] <=> $b['return_fare'];
   }

   if ($a['one_way_fare'] != $b['one_way_fare']) {
      return $a['one_way_fare'] <=> $b['one_way_fare'];
   }

   return strnatcasecmp($a['destination'], $b['destination']);
});

Сортировка по return_fare:

usort($data, function($a, $b) {
   return $a['return_fare'] <=> $b['return_fare'];
});

Примечание: вам не нужно использовать анонимную функцию с usort!

function cmp($a, $b) {
   return $a['return_fare'] <=> $b['return_fare'];
}

usort($data, 'cmp');


// Use a function inside a class:
class MyClass {
   public static function compare($a, $b) {
      return $a['return_fare'] <=> $b['return_fare'];
   }
}

usort($data, ['MyClass', 'compare']);

Вы также можете связать их с помощью оператора Элвиса (?:):

usort($data, function($a, $b) {
      return $a['return_fare'] <=> $b['return_fare'] ?:
             $a['one_way_fare'] <=> $b['one_way_fare'] ?:
             strnatcasecmp($a['destination'], $b['destination']);
});

В последнем примере использовались оператор космического корабля (<=>) и оператор Элвиса (?:).Разве программирование не прекрасно?

0 голосов
/ 03 января 2011

Ооо, мне снова удалось решить свой собственный вопрос ....

function array_multi_sort($array, $on1,$on2, $order=SORT_ASC) 
{

    foreach($array as $key=>$value){
        $one_way_fares[$key] = $value[$on2];
        $return_fares[$key] = $value[$on1];
    }

    array_multisort($return_fares,$order,$one_way_fares,$order,$array);
}

Дело в том, что я пропустил последний параметр $ array в array_multisort($return_fares,$order,$one_way_fares,$order,$array);

раньше!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...