如何删除数组元素然后重新索引数组?
Posted
技术标签:
【中文标题】如何删除数组元素然后重新索引数组?【英文标题】:How to Remove Array Element and Then Re-Index Array? 【发布时间】:2011-07-10 05:13:05 【问题描述】:我在使用数组时遇到了一些问题。我有一个要修改的数组,如下所示。我想通过索引删除它的元素(元素),然后重新索引数组。有可能吗?
$foo = array(
'whatever', // [0]
'foo', // [1]
'bar' // [2]
);
$foo2 = array(
'foo', // [0], before [1]
'bar' // [1], before [2]
);
【问题讨论】:
【参考方案1】:一段时间后,我会将所有数组元素(不包括这些不需要的元素)复制到新数组中
【讨论】:
【参考方案2】:PHP 7.4 中的 2020 年基准测试
对于那些对当前答案不满意的人,我做了一个小基准脚本,任何人都可以从 CLI 运行。
我们将比较两种解决方案:
unset() with 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";
如您所见,这个想法很简单:
创建两个具有相同 100k 项的数组(随机生成的字符串) 使用 unset() 和 array_values() 从第一个数组中删除 10k 项以重新索引 使用 array_splice() 从第二个数组中删除 10k 个第一个项目 测量两种方法的时间上述脚本在我的 Dell Latitude i7-6600U 2.60GHz x 4 和 15.5GiB RAM 上的输出:
php v7.4.8
unset & array_values: 29.089932918549s
array_splice: 17.94264793396s
结论:array_splice 的性能几乎是 unset 和 array_values 的两倍。
所以:array_splice 是赢家!
【讨论】:
【参考方案3】:array_splice($array, array_search(array_value, $array), 1);
【讨论】:
其中array_value 将是'whatever' 解释属于问题,不是作为评论发布在问题下。【参考方案4】:如果您使用array_merge
,这将重新索引键。手册指出:
输入数组中带有数字键的值将重新编号为 在结果数组中从零开始递增键。
http://php.net/manual/en/function.array-merge.php
这是我找到原始答案的地方。
http://board.phpbuilder.com/showthread.php?10299961-Reset-index-on-array-after-unset()
【讨论】:
【参考方案5】:你最好使用 array_shift()
。这将返回数组的第一个元素,将其从数组中删除并重新索引数组。一种高效的方法。
【讨论】:
当您想要检索然后删除第一个数组元素并在此过程中重新索引数组时,这很好。如果需要,它的对应函数array_pop()
将检索并删除最后一个数组元素。但是,这两个函数都不能作用于数组中间的元素。
虽然这是正交相关的,但问题显然是关于数组的 any 元素,而不仅仅是第一个元素。【参考方案6】:
Unset($array[0]);
Sort($array);
我不知道为什么这被否决了,但如果有人费心尝试它,你会发现它有效。
对数组使用 sort 会重新分配数组的键。唯一的缺点是它对值进行排序。
由于键显然会被重新分配,即使使用array_values
,值是否被排序都无关紧要。
【讨论】:
即使重新分配键,在正确的答案中,也会保持初始顺序。 “我想通过索引删除它的元素(元素),然后重新索引数组。可以吗?” @s3v3n OP 从未要求维持初始顺序。我只是提供了一个可行的解决方案并按照说明进行。 问题是2岁。放手吧! @s3v3n 这不是怨恨。我只是想知道为什么。显然要在以后的答案中改进。我同意有更好的方法,但是这个答案这么糟糕有什么原因吗?是性能吗?等等?与我在 SO 上的原因相同,既要学习又要教。 在正常情况下,程序员很可能会以与输入完全相同的顺序需要这些值。让我们以数据库中应该显示在表格中的一些行为例;或聊天应用程序,其中回复的顺序应完全相同。示例的数量可以是无限的,关键是在大多数情况下,顺序需要相同,或者至少程序员希望数组中元素的顺序相同。【参考方案7】:尝试:
$foo2 = array_slice($foo, 1);
【讨论】:
这仅适用于第一个元素,而不是任意元素。【参考方案8】:array_splice($array, 0, 1);
http://php.net/manual/en/function.array-splice.php
【讨论】:
小心在循环中使用它,因为它会使循环的数组索引和实际数组的索引不同步。【参考方案9】:unset($foo[0]); // remove item at index 0
$foo2 = array_values($foo); // 'reindex' array
【讨论】:
如果需要一次删除多个项目,这比 deceze 的解决方案要好 - 如果事先收集了这些项目的索引。一旦对第一项使用 array_splice,就会丢失其余项的索引。 值得注意的是,您可以在一次取消设置调用unset($foo[0], $foo[3], $bar[1]);
中取消设置多个变量/数组索引以上是关于如何删除数组元素然后重新索引数组?的主要内容,如果未能解决你的问题,请参考以下文章