如果某些项目满足特定条件,则将它们移动到数组的末尾

Move some items to the end of the array if they fulfill a specific condition

我有一组路径要排序...

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函数来实现吗?

您可以使用 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
)

在您的具体示例中,您可以简单地使用 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"
}

如果不是这样,请告诉我,我会做其他事情

...这是新方法参考评论:

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

可能可以写得更好,但应该可行