Выборочная сортировка массива по входной строке и положению

У меня есть массив. Это выглядит как:

$arr = [
'0' => ['id'=>9, 'q'=>'motor', 'pos'=>1],
'1' => ['id'=>10, 'q'=>'NULL', 'pos'=>0],
'2' => ['id'=>7, 'q'=>'motor', 'pos'=>2],
'3' => ['id'=>8, 'q'=>'NULL',  'pos'=>0],
'4' => ['id'=>11, 'q'=>'motor','pos'=>3],
'5' => ['id'=>11, 'q'=>'exhaust','pos'=>1]
];

Как я могу отсортировать данные выше, чтобы они выглядели так (если q = ‘motor’ находится внутри строки поиска):

 $arr = [
'0' => ['id'=>9, 'q'=>'motor', 'pos'=>1],
'2' => ['id'=>7, 'q'=>'motor', 'pos'=>2],
'4' => ['id'=>11, 'q'=>'motor','pos'=>3],
'1' => ['id'=>10, 'q'=>'NULL', 'pos'=>0],
'3' => ['id'=>8, 'q'=>'NULL',  'pos'=>0],
'5' => ['id'=>11, 'q'=>'exhaust','pos'=>1]
];

Так:

function custom_sort($input_query, $arr) {
foreach($arr as $key=>$row) {
if (strpos($input_query, $row['q'])) {
... How to Sort By Pos?
}
}
}

Спасибо!

Обновлено (вопрос / ответ)
PS: я пытаюсь использовать пользовательскую переменную в качестве ввода: $ q

usort($arr, function($a, $b) use ($q) {
if ($a['q'] == $q) {
if($b['q'] == $q) {
return ($a['pos'] > $b['pos']) ? 1 : -1;
}
return -1;
}
if ($b['q'] == $q) {
return 1;
}
return 0;
});

И функция перестает работать. Как я могу решить это?

1

Решение

Вот usort которая обрабатывает ваши требования, обернутая в функцию, которая преобразует массив на место:

  1. Предметы с q ключ, содержащий $query будет размещен в передней части массива.

  2. Предметы с q ключ, содержащий $query будут отсортированы по возрастанию их pos значение.

  3. Все остальное будет отсортировано по pos значение.

function custom_sort($query, &$arr) {
usort($arr, function($a, $b) use ($query) {
$in_a = strpos($a['q'], $query) !== false;
$in_b = strpos($b['q'], $query) !== false;

if ($in_a && !$in_b) {
return -1;
}
if (!$in_a && $in_b) {
return 1;
}

return $a['pos'] - $b['pos'];
});
}

custom_sort("motor", $arr);

Проверьте это на большом наборе данных в этом РЕПЛ.

2

Другие решения

Ты можешь использовать usort

usort($arr, function($a, $b) {
if ($a['q'] == 'motor') {
if($b['q'] == 'motor') {
return ($a['pos'] > $b['pos']) ? 1 : -1;
}
return -1;
}
if ($b['q'] == 'motor') {
return 1;
}
return 0;
});

Если вам нужен другой порядок, просто измените функцию в соответствии с вашими потребностями.

2

U сортировка поможет вам здесь

usort( $arr, function ( $a, $b ) {
if ( $a['q'] === $b['q'] ) {
return $a['pos'] < $b['pos'] ? -1 : 1;
}
if ( $a['q'] === 'motor' ) {
return -1;
}
if ( $b['q'] === 'motor' ) {
return 1;
}
return 0;
} );
1
По вопросам рекламы [email protected]