Прежде всего, если ваш входной массив является результирующим набором запроса MySQL, вы должны сортировать данные с помощью предложения ORDER BY.FIELD()
- отличный инструмент для работы, с небольшой странностью, что вам нужно изменить логику сортировки и написать DESC
после функции.
Ресурс: https://www.electrictoolbox.com/mysql-order-specific-field-values/ (прокрутите вниз до "готча ")
Демонстрация SQL Fiddle: http://sqlfiddle.com/#!9/6b996f/1
Помимо этого, я предложу две улучшенные версии решений Найджела и Эдди, использующих некоторые преимущества php7 +.То, что вы выберете для реализации, будет связано с:
- Хотите ли вы, чтобы элементы с дублирующимися значениями
id
"выжили" в процессе - Какой из них работает более эффективнодля ваших фактических данных проекта (размер вашего входного массива и ваш массив пользовательских заказов)
- Личные предпочтения (оба фрагмента могут быть разумно записаны в 3-5 строк, поэтому краткость небольшая часть критериев)
PHP Demo
$array = [
(object)['id' => 8],
(object)['id' => 7],
(object)['id' => 5]
];
$order = [5, 8, 1]; // custom sort order
$order = array_flip($order); // restructure for easy lookup with isset()
$order[''] = max(array_column($array, 'id')) + 1; // append value higher than max for outlying ids
usort($array, function($a, $b) use ($order) {
return ($order[$a->id] ?? $order['']) <=> ($order[$b->id] ?? $order['']);
});
var_export($array);
* обратите внимание, что я мог бы передать $outlier
в область действия пользовательской функции в качестве второго аргумента use
и заменить все переменные $order['']
на $outlier
, но я выбралдобавьте данные выбросов в массив поиска.
* Я использовал круглые скобки в своей пользовательской функции не только для улучшения читабельности, но и для гарантии того, что оценка выполняется должным образом - на самом деле я не удосужился проверить,оценка яТо же самое без группировки в скобках.
Решение № 2: array_replace () перевернутый и отфильтрованный массив сортировки с массивом с ключами
( PHP Demo * )
$array = [
(object)['id' => 8],
(object)['id' => 7],
(object)['id' => 5]
];
$order = [5, 8, 1];
$order = array_flip($order); // flip for future key comparisons
$keyed = array_column($array, null, 'id'); // declare id values as new keys
$filtered_order = array_intersect_key($order, $keyed); // remove unwanted order keys
$replaced = array_replace($filtered_order, $keyed); // apply objects to output array
var_export(array_values($replaced)); // re-index the output (if desired)
* обратите внимание, что это не сгенерирует слишком большой массив значений null
и не удалит значения, которые являются "ложными".
* Я снова сообщучто использование array_column()
повредит данные, если во входном массиве есть повторяющиеся значения id
.