如何删除数组元素然后重新索引数组?

daG*_*vis 203 php arrays indexing

我有阵列的麻烦.我有一个我想要修改的数组,如下所示.我想通过索引删除它的元素(元素),然后重新索引数组.可能吗?

$foo = array(

    'whatever', // [0]
    'foo', // [1]
    'bar' // [2]

);

$foo2 = array(

    'foo', // [0], before [1]
    'bar' // [1], before [2]

);
Run Code Online (Sandbox Code Playgroud)

xzy*_*fer 449

unset($foo[0]); // remove item at index 0
$foo2 = array_values($foo); // 'reindex' array
Run Code Online (Sandbox Code Playgroud)

  • 值得注意的是,你可以在一个unset调用`unset($ foo [0],$ foo [3],$ bar [1])中取消设置多个变量/数组索引;` (22认同)
  • 这正是我想要发布的内容,+ 1. (6认同)
  • 如果需要一次删除多个项目 - 如果事先收集了这些项目的索引,这比deceze的解决方案更好.在第一个项目上使用array_splice后,将丢失其余项目的索引. (4认同)

dec*_*eze 41

array_splice($array, 0, 1);
Run Code Online (Sandbox Code Playgroud)

http://php.net/manual/en/function.array-splice.php

  • 小心在循环中使用它,因为它使循环的数组索引和实际的数组不同步. (2认同)

小智 28

你最好用array_shift().这将返回数组的第一个元素,将其从数组中删除并重新索引数组.一体化的有效方法.

  • 当你想要检索然后删除第一个数组元素,在进程中重新索引数组时,这很好.如果需要,它的对应函数`array_pop()`将检索并删除最后一个数组元素.但是,两个函数都不能作用于数组中间的元素. (2认同)
  • 虽然这是正交相关的,但问题明确是关于数组的*任何*元素,而不仅仅是第一个元素。 (2认同)

小智 9

array_splice($array, array_search(array_value,$array),1);
Run Code Online (Sandbox Code Playgroud)


fro*_*ous 8

Unset($array[0]); 

Sort($array); 
Run Code Online (Sandbox Code Playgroud)

我不知道为什么要拒​​绝它,但是如果有人不愿意尝试它,您会注意到它可行。在数组上使用sort会重新分配数组的键。唯一的缺点是它对值进行排序。由于显然可以重新分配键,即使使用array_values,也可以对值进行排序与​​否。

  • 即使重新分配了按键,也将以正确的答案保留初始顺序。 (9认同)
  • “我想通过索引删除它的元素,然后重新索引数组。这可能吗?” @s3v3n OP从未要求维持初始顺序。我只是提供了一个可行的解决方案并执行所说明的操作。 (2认同)

hsz*_*hsz 5

尝试使用:

$foo2 = array_slice($foo, 1);
Run Code Online (Sandbox Code Playgroud)


bar*_*ell 5

2020 年 PHP 7.4 基准测试

对于那些对当前答案不满意的人,我做了一个小基准脚本,任何人都可以从 CLI 运行。

我们将比较两种解决方案:

unset() 与 array_values() VS array_splice()

<?php

echo 'php v' . phpversion() . "\n";

$itemsOne = [];
$itemsTwo = [];

// populate items array with 100k random strings
for ($i = 0; $i < 100000; $i++) {
    $itemsOne[] = $itemsTwo[] = sha1(uniqid(true));
}

$start = microtime(true);

for ($i = 0; $i < 10000; $i++) {
    unset($itemsOne[$i]);
    $itemsOne = array_values($itemsOne);
}

$end = microtime(true);

echo 'unset & array_values: ' . ($end - $start) . 's' . "\n";

$start = microtime(true);

for ($i = 0; $i < 10000; $i++) {
    array_splice($itemsTwo, $i, 1);
}

$end = microtime(true);

echo 'array_splice: ' . ($end - $start) . 's' . "\n"; 
Run Code Online (Sandbox Code Playgroud)

如您所见,这个想法很简单:

  • 创建两个具有相同 100k 项(随机生成的字符串)的数组
  • 使用 unset() 和 array_values() 从第一个数组中删除 10k 个第一项以重新索引
  • 使用 array_splice() 从第二个数组中删除 10k 个第一项
  • 测量两种方法的时间

以上脚本在我的戴尔 Latitude i7-6600U 2.60GHz x 4 和 15.5GiB RAM 上的输出:

php v7.4.8
unset & array_values: 29.089932918549s
array_splice: 17.94264793396s
Run Code Online (Sandbox Code Playgroud)

结论:array_splice 的性能几乎是 unset 和 array_values 的两倍。

所以:array_splice 是赢家!

  • 第三个测试是 unset() 全部 10k,然后运行 ​​array_values() 重新索引一次,而不是每次循环都重新索引。对于我来说,使用你的脚本比 array_splice() 快约 5%。 (2认同)