PHP-Сортування масиву на основі іншого масиву?

OK, I already got this question in stackoverflow but sadly it's in JavaScript - Javascript - sort array based on another array

і я хочу його в PHP

$data = array(
   "item1"=>"1",
   "item2"=>"3",
   "item3"=>"5",
   "item4"=>"2",
   "item5"=>"4"
);

щоб відповідати розташуванню цього масиву:

sortingArr = array("5","4","3","2","1");

і вихід, який я шукаю:

$data = array(
    "item3"=>"5",
    "item5"=>"4",
    "item2"=>"3",
    "item4"=>"2",
    "item1"=>"1"
 );

Будь-яка ідея, як це можна зробити? Дякую.

14
Використовуйте usort() , з функцією порівняння, яка порівнює позиції значень у $ sortingArr .
додано Автор Barmar, джерело
Ви можете asort() обидва.
додано Автор Albzi, джерело

7 Відповіді

For a detailed answer, why array_multisort does not match your needs, view this answer, please: PHP array_multisort not sorting my multidimensional array as expected

Коротше кажучи: Ви хочете відсортувати масив на основі заздалегідь визначеного порядку. Відповідь також наведено там, але я скопіював одне рішення для цієї відповіді:

Скористайтеся usort і array_flip , тому ви зможете перетворити ваш масив індексування (ValueByPosition) на масив PositionByValue .

    $data = array(
   "item1"=>"1",
   "item2"=>"3",
   "item3"=>"5",
   "item4"=>"2",
   "item5"=>"4"
);

usort($data, "sortByPredefinedOrder");

function sortByPredefinedOrder($leftItem, $rightItem){
  $order = array("5","4","3","2","1");

  $flipped = array_flip($order);

  $leftPos = $flipped[$leftItem];
  $rightPos = $flipped[$rightItem];
  return $leftPos >= $rightPos;   
}

print_r($data);
// usort: Array ( [0] => 5 [1] => 4 [2] => 3 [3] => 2 [4] => 1 )
// uasort: Array ( [item3] => 5 [item5] => 4 [item2] => 3 [item4] => 2 [item1] => 1 )

Проте для цього потрібно передбачити всі можливі елементи всередині попередньо визначеного масиву замовлень або виконати інші елементи відповідним чином.

Якщо потрібно зберегти ключі assoc, використовуйте uasort замість usort .

8
додано

Досить просто?

$data = array(
   "item1"=>"1",
   "item2"=>"3",
   "item3"=>"5",
   "item4"=>"2",
   "item5"=>"4"
);

$sortingArr = array("5","4","3","2","1");

$result = array();//result array
foreach($sortingArr as $val){//loop
    $result[array_search($val, $data)] = $val;//adding values
}
print_r($result);//print results

Вивід:

Array
(
    [item3] => 5
    [item5] => 4
    [item2] => 3
    [item4] => 2
    [item1] => 1
)
7
додано
До тих пір, поки це не буде зроблено в критичній частині програми, а дані досить малі, вона зробить свою роботу легко зрозумілою.
додано Автор flu, джерело
Я не думаю, що це хороше оперативне рішення для пам'яті. У цьому випадку функція usort набагато простіше і швидше. Але все ж це робоче рішення для малих масивів. BR.
додано Автор Jacek Kowalewski, джерело

Подивіться на мій наступний фрагмент, щоб відсортувати масив на основі іншого масиву

$res_arr = array(); 
for ($i = 0; $i < count($sortingArr); $i++) {
     for ($j = 0; $j < count($data); $j++) {
          if($data[$j] == $sortingArr[$i]) {
             $res_arr[] = $data[$j];
             break;
          }
     }
}
// $res_array is your sorted array now
1
додано

Look at code snippet to make a multidimensional array sort in order of input

$input_format_list = [4, 1];
$data = array(
    "0" => array(
        "School" => array(
            "id" => 1,
             "name" => "ST.ANN'S HIGH SCHOOL",
        )
    ),     
    "1" => array(
        "School" => array(
            "id" => 4,
            "name" => "JYOTI VIDHYA VIHAR",
        )
    )
);   

$result = array();//result array
foreach($input_format_list as $key => $value){//loop
    foreach ($data as $k => $val) {
        if ($data[$k]['School']['id'] === $value) {
           $result[$key] = $data[$k];
        }
    }            
}            
return $result;
1
додано

Перегляньте array_multisort . Я не зовсім впевнений, як його використовувати, тому що ніколи не знайшов для нього практичного використання (я віддаю перевагу використовувати usort для чіткого визначення термінів), але він може працювати для вас.

0
додано
Отже, якщо перший масив - це той, що містить потрібний порядок, то це не означає, що масив $ data як другий сортується відповідно ...? Я не знаю, як я сказав, ніколи не використовував цю функцію!
додано Автор Niet the Dark Absol, джерело
Я не думаю, що array_multisort() робить те, що йому потрібно. Він буде сортувати один масив нормально, а потім змінити порядок іншого масиву відповідно.
додано Автор Barmar, джерело
Я також не використовував його, але приклади на сторінці документації, здається, не відповідають тому, що він хоче. Дивіться Приклад №1. Вона не зберігає жодного вхідного тексту у своєму початковому порядку.
додано Автор Barmar, джерело
Дивіться мій пост для прикладу, як працює масив мультисорту. Ні, це не буде працювати. array_multisort "сортує" масив, визначаючи порядок і переміщуючи записи інших масивів вгору або вниз. Не те, що тут потрібно.
додано Автор dognose, джерело
Я думаю, це працювало для мене: array_multisort ($ sortingArr, SORT_ASC, $ data, SORT_ASC);
додано Автор Hayden Thring, джерело
Я використав його для сортування таблиць на основі користувача введення його, безумовно, дивна функція, але іноді корисно я можу опублікувати приклад, але його безпосередньо не пов'язані з вашим питанням я боюся
додано Автор Dave, джерело
<?php 
$data = array(
   "item1"=>"1",
   "item2"=>"3",
   "item3"=>"5",
   "item4"=>"2",
   "item5"=>"4"
);
$result=array_flip($data);

krsort($result);

$result=array_flip($result);

print_r($result);

//use rsort for the index array

$sortingArr = array("5","4","3","2","1");

print_r($sortingArr);
0
додано
Насправді немає сенсу сортувати значення $ data за значеннями. Оскільки $ sortingArr може не бути низхідними значеннями. Також, використовуючи array_flip , а потім krsort , це просто потворно, можна безпосередньо використовувати rsort .
додано Автор HamZa, джерело
$ sortingArr також сортується в порядку убування за допомогою rsort. Обидва масиви тепер доступні в порядку убування
додано Автор Sundar, джерело

використовуючи usort() правильний шлях , я думаю

Сортування масиву за значеннями за допомогою користувацької функції порівняння

Ви можете зробити так:

$data = array(
   "item1"=>"1",
   "item2"=>"3",
   "item3"=>"5",
   "item4"=>"2",
   "item5"=>"4"
);

$sortingArr = array("5","4","3","2","1");

$keys = array_flip($sortingArr);

usort($data, function ($a, $b) use ($keys) {
    return $keys[$a] > $keys[$b] ? 1 : -1;
});

print_r($data);

// Output
// Array ( [0] => 5 [1] => 4 [2] => 3 [3] => 2 [4] => 1 )

live example: https://3v4l.org/75cnu

0
додано
Ukrainian PHP comunity
Ukrainian PHP comunity
885 учасників

dev-ua/php