Переместить некоторые элементы в конец массива, если они удовлетворяют определенному условию

У меня есть массив путей, которые я хотел бы отсортировать …

Array
(
/something/foo1
/something/special/foo2
/something/foo3
/something/special/foo4
/something/foo5
/something/special/foo6
)

… так что все пути, которые содержат /special/ в конечном итоге в конце массива, как это:

Array
(
/something/foo1
/something/foo3
/something/foo5
/something/special/foo2
/something/special/foo4
/something/special/foo6
)

Исходный порядок сортировки путей должен оставаться неизменным (поэтому 1,2,3,4,5,6 => 1,3,5,2,4,6). Есть ли элегантный способ сделать это? Можно ли это реализовать с помощью функции usort?

0

Решение

ты можешь использовать unset и добавить [], вот так

$x = array(1,2,3);
$x[] = $x[1];
unset($x[1]);
print_r($x);

Array
(
[0] => 1
[2] => 3
[3] => 2
)

Таким образом, вы можете перебрать массив, проверить каждый элемент и перевернуть до конца те, которые содержат шаблон.

$len = count($a);
for ($i=0; $i<$len; $i++) {
if (...) {
$a[] = $a[i];
unset($a[i]);
}
}

Изменить: массивы php являются списки, хэши и массивы одновременно. Можно переместить элемент до конца, сохранив его индекс! Например

$a = array(1,2,3);

$t = $a[1];
unset($a[1]);
$a[1] = $t;

print_r($a);
Array
(
[0] => 1
[2] => 3
[1] => 2
)
1

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

В вашем конкретном примере вы можете просто использовать asort($array);

Но это при условии, что foo — это всегда foo.

Выход:

array(6) {
[0]=>
string(15) "/something/foo1"[2]=>
string(15) "/something/foo3"[4]=>
string(15) "/something/foo5"[1]=>
string(23) "/something/special/foo2"[3]=>
string(23) "/something/special/foo4"[5]=>
string(23) "/something/special/foo6"}

Если это не так, дайте мне знать, и я сделаю что-то еще

… вот новый метод ref комментарий:

$array  = array(
'/something/zoo',
'/something/special/foo',
'/something/loo',
'/something/special/goo',
'/something/boo',
'/something/special/poo'
);
uasort($array, function($a, $b) {
$specialInA = strpos($a, '/special/') !== false;
$specialInB = strpos($b, '/special/') !== false;
if ($specialInA > $specialInB) {
return 1;
}
if ($specialInB > $specialInA) {
return -1;
}
return $a > $b;
});

Выход:

array(6) {
[4]=>
string(14) "/something/boo"[2]=>
string(14) "/something/loo"[0]=>
string(14) "/something/zoo"[1]=>
string(22) "/something/special/foo"[3]=>
string(22) "/something/special/goo"[5]=>
string(22) "/something/special/poo"}

Может быть, написано лучше, но должно работать

1

По вопросам рекламы [email protected]