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

时间:2015-02-21 02:44:55

标签: php arrays sorting usort

我有一系列我想要排序的路径......

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

2 个答案:

答案 0 :(得分:1)

您可以使用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 :(得分: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"
}

如果情况并非如此,请告诉我,我会做其他事情

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

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

可能写得更好但应该有效