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

0

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

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?

Теги:
arrays
sorting
usort

2 ответа

1
Лучший ответ

вы можете использовать unset и append [], например

$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
)
  • 0
    Это не поддерживает связь индекса в соответствии с запросом
  • 0
    нужно было поддерживать не ассоциацию индекса, а порядок сортировки. Ассоциация также может поддерживаться путем явного присвоения индекса; $t = $a[$i]; unset($a[$i]); $a[$i] = $t; с $t = $a[$i]; unset($a[$i]); $a[$i] = $t; переместит $ t в конец с тем же индексом, что и раньше. У Php действительно классные массивы.
Показать ещё 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 comment:

$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"
}

Возможно, лучше написано лучше, но должно работать

  • 0
    О, я, наверное, должен был упомянуть об этом раньше. Фактические пути совершенно разные. Просто special часть остается прежней. Спасибо!
  • 0
    Понял, сделаю правку ...
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню