Сортировка массива php массивов по индивидуальному заказу

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

Array ( [0] => Array ( [id] = 7867867, [title] = 'Some Title'), [1] => Array ( [id] = 3452342, [title] = 'Some Title'), [2] => Array ( [id] = 1231233, [title] = 'Some Title'), [3] => Array ( [id] = 5867867, [title] = 'Some Title') ) 

Необходимость идти в определенном порядке:

  1. 3452342
  2. 5867867
  3. 7867867
  4. 1231233

Как мне это сделать? Я уже сортировал массивы и читал много других сообщений об этом, но они всегда основаны на сравнении (например, valueA <valueB).

Помощь приветствуется.

Related of "Сортировка массива php массивов по индивидуальному заказу"

Вы можете использовать usort() чтобы точно usort() как массив должен быть отсортирован. В этом случае массив $order может использоваться в функции сравнения.

В приведенном ниже примере используется closure облегчающее жизнь.

 $order = array(3452342, 5867867, 7867867, 1231233); $array = array( array('id' => 7867867, 'title' => 'Some Title'), array('id' => 3452342, 'title' => 'Some Title'), array('id' => 1231233, 'title' => 'Some Title'), array('id' => 5867867, 'title' => 'Some Title'), ); usort($array, function ($a, $b) use ($order) { $pos_a = array_search($a['id'], $order); $pos_b = array_search($b['id'], $order); return $pos_a - $pos_b; }); var_dump($array); 

Ключом к этой работе является сравнение значений, являющихся позициями id s в массиве $order .

Функция сравнения работает путем нахождения позиций идентификаторов двух элементов для сравнения в массиве $order . Если $a['id'] приходит до $b['id'] в массиве $order , тогда возвращаемое значение функции будет отрицательным ( $a меньше так «плавает»). Если $a['id'] появляется после $b['id'] тогда функция возвращает положительное число ( $a больше, поэтому «снижается»).

Наконец, нет особых причин для использования закрытия; это просто мой способ быстро написать эти виды отброшенных функций. Он также может использовать обычную именованную функцию.

Расширение ответа salathe для этого дополнительного требования:

Теперь что происходит, когда я добавляю элементы в массив, а не в сортировку? Меня не волнует, какой порядок они появляются, до тех пор, пока это происходит после тех, которые я указал.

Вам нужно добавить два дополнительных условия в функцию сортировки:

  1. Элемент «не заботясь» должен считаться больше, чем «заботиться о» предметах
  2. Два предмета «не заботясь» должны считаться равными

Таким образом, пересмотренный код будет:

 $order = array( 3452342, 5867867, 7867867, 1231233 ); $array = array( array("id" => 7867867, "title" => "Must Be #3"), array("id" => 3452342, "title" => "Must Be #1"), array("id" => 1231233, "title" => "Must Be #4"), array("id" => 5867867, "title" => "Must Be #2"), array("id" => 1111111, "title" => "Dont Care #1"), array("id" => 2222222, "title" => "Dont Care #2"), array("id" => 3333333, "title" => "Dont Care #3"), array("id" => 4444444, "title" => "Dont Care #4") ); function custom_compare($a, $b){ global $order; $a = array_search($a["id"], $order); $b = array_search($b["id"], $order); if($a === false && $b === false) { // both items are dont cares return 0; // a == b } else if ($a === false) { // $a is a dont care item return 1; // $a > $b } else if ($b === false) { // $b is a dont care item return -1; // $a < $b } else { return $a - $b; } } shuffle($array); // for testing var_dump($array); // before usort($array, "custom_compare"); var_dump($array); // after 

Вывод:

 Before | After -------------------------------+------------------------------- array(8) { | array(8) { [0]=> | [0]=> array(2) { | array(2) { ["id"]=> | ["id"]=> int(4444444) | int(3452342) ["title"]=> | ["title"]=> string(12) "Dont Care #4" | string(10) "Must Be #1" } | } [1]=> | [1]=> array(2) { | array(2) { ["id"]=> | ["id"]=> int(3333333) | int(5867867) ["title"]=> | ["title"]=> string(12) "Dont Care #3" | string(10) "Must Be #2" } | } [2]=> | [2]=> array(2) { | array(2) { ["id"]=> | ["id"]=> int(1231233) | int(7867867) ["title"]=> | ["title"]=> string(10) "Must Be #4" | string(10) "Must Be #3" } | } [3]=> | [3]=> array(2) { | array(2) { ["id"]=> | ["id"]=> int(1111111) | int(1231233) ["title"]=> | ["title"]=> string(12) "Dont Care #1" | string(10) "Must Be #4" } | } [4]=> | [4]=> array(2) { | array(2) { ["id"]=> | ["id"]=> int(5867867) | int(2222222) ["title"]=> | ["title"]=> string(10) "Must Be #2" | string(12) "Dont Care #2" } | } [5]=> | [5]=> array(2) { | array(2) { ["id"]=> | ["id"]=> int(2222222) | int(1111111) ["title"]=> | ["title"]=> string(12) "Dont Care #2" | string(12) "Dont Care #1" } | } [6]=> | [6]=> array(2) { | array(2) { ["id"]=> | ["id"]=> int(3452342) | int(3333333) ["title"]=> | ["title"]=> string(10) "Must Be #1" | string(12) "Dont Care #3" } | } [7]=> | [7]=> array(2) { | array(2) { ["id"]=> | ["id"]=> int(7867867) | int(4444444) ["title"]=> | ["title"]=> string(10) "Must Be #3" | string(12) "Dont Care #4" } | } } | } 

Вам нужно определить свою собственную функцию сравнения и использовать usort или uasort если вы хотите поддерживать ассоциацию индексов.

Вот как я решил проблему сортировки в многомерном массиве заказов ASC, надеюсь, что это поможет

  $arrayFilter = array( array( 'product_tag' => 'xenia', 'id' => 4 ), array ( 'product_tag' => 'worn', 'id' => 5 ), array ( 'product_tag' => 'woven', 'id' => 3 ), array ( 'product_tag' => 'nude', 'id' => 1 )); for ($i = 0; $i < sizeof($arrayFilter); $i++) { for ($j=$i+1;$j <sizeof($arrayFilter); $j++) { if ($arrayFilter[$i]['id'] > $arrayFilter[$j]['id']) { $c = $arrayFilter[$i]; $arrayFilter[$i] = $arrayFilter[$j]; $arrayFilter[$j] = $c; } } } print_r($arrayFilter); 

ВЫВОД:

 Array ( [0] => Array ( [product_tag] => nude [id] => 1 ) [1] => Array ( [product_tag] => woven [id] => 3 ) [2] => Array ( [product_tag] => xenia [id] => 4 ) [3] => Array ( [product_tag] => worn [id] => 5 ) ) 

@salathe Для тех из вас, кто с трудом понимает, что делает утиль Salathe:

Каждый элемент в массиве $ array является «чемпионом» в турнире, который должен быть в начале нового массива (кроме, вместо того, чтобы быть номером один, они хотят быть числом 0).

$ a является чемпионом дома, а $ b противником в матче.

$ pos_a и $ pos_b от обратного вызова – какие атрибуты будут использоваться в борьбе за чемпионов a и b. В этом случае этот атрибут является индексом идентификатора чемпиона в $ order.

Затем идет бой по возвращении. Теперь мы посмотрим, лучше ли более или менее атрибут. В битве за битву домашний чемпион хочет отрицательное число, поэтому он может быть скорее в массиве. Выездной чемпион хочет получить положительное число. И должно быть 0, это галстук.

Итак, следуя этой аналогии, когда атрибут «Чемпионы» (индекс в $ order) вычитается из атрибута home Teams, чем больше атрибут «away champion», тем меньше вероятность выиграть, получив положительное число. Однако, если вы изменили способ использования атрибутов, теперь атрибут домашнего чемпиона вычитается из игры чемпиона. В этом случае большее число для чемпиона в гостях с большей вероятностью заставит его завершить матч в положительном числе.

Код будет выглядеть так:

примечание: код запускается много раз, так как у реального турнира много битв, чтобы решить, кто первым (то есть 0 / начало массива)

 //tournament with goal to be first in array usort($champions, function ($home, $away) use ($order) { $home_attribute = array_search($a['id'], $order); $away_attribute = array_search($b['id'], $order); //fight with desired outcome for home being negative and away desiring positive return $home_attribute - $away_attribute; });