获取数组的最后一个元素而不删除它的最好方法是什么?
好,
我知道所有关于array_pop()
,但删除最后一个元素。 获取数组的最后一个元素而不删除它的最好方法是什么?
编辑:这是一个奖金:
$array = array('a' => 'a', 'b' => 'b', 'c' => 'c');
甚至
$array = array('a', 'b', 'c', 'd'); unset($array[2]); echo $array[sizeof($array) - 1]; // Output: PHP Notice: Undefined offset: 2 in - on line 4
简短而甜蜜。
我想出了解决scheme,以消除错误信息,并保留一行表格和高效的性能:
$lastEl = array_values(array_slice($array, -1))[0];
– 以前的解决scheme
$lastEl = array_pop((array_slice($array, -1)));
注意:需要额外的括号以避免PHP Strict standards: Only variables should be passed by reference
。
尝试
$myLastElement = end($yourArray);
重置它(谢谢@ hopeseekr):
reset($yourArray);
链接到手册
@David Murdoch补充说: $myLastElement = end(array_values($yourArray));// and now you don't need to call reset().
在E_STRICT上会产生警告
Strict Standards: Only variables should be passed by reference
感谢o_O Tync和大家!
array_slice($array, -1)
什么问题? (见手册: http : //us1.php.net/array_slice )
array_slice()
返回一个数组。 可能不是你在找什么。 你想要的元素。
在这个线程中的许多答案向我们提供了许多不同的select。 为了能够从中select,我需要了解他们的行为和performance。 在这个答案中,我将与您分享我的发现,基于PHP版本5.6.29
和7.1.0
。 我将testing的选项是:
- 选项1.
$x = array_values(array_slice($array, -1))[0];
- 选项2.
$x = array_slice($array, -1)[0];
- 选项3.
$x = array_pop((array_slice($array, -1)));
- 选项4.
$x = array_pop((array_slice($array, -1, 1)));
- 选项5.
$x = end($array); reset($array);
$x = end($array); reset($array);
- 选项6.
$x = end((array_values($array)));
- 选项7.
$x = $array[count($array)-1];
- 选项8.
$keys = array_keys($array); $x = $array[$keys[count($keys)-1]];
$keys = array_keys($array); $x = $array[$keys[count($keys)-1]];
- 选项9.
$x = $array[] = array_pop($array);
testinginput:
- null =
$array = null;
- empty =
$array = [];
- last_null =
$array = ["a","b","c",null];
- auto_idx =
$array = ["a","b","c","d"];
- shuffle =
$array = []; $array[1] = "a"; $array[2] = "b"; $array[0] = "c";
$array = []; $array[1] = "a"; $array[2] = "b"; $array[0] = "c";
- 100 =
$array = []; for($i=0;$i<100;$i++) { $array[] = $i; }
$array = []; for($i=0;$i<100;$i++) { $array[] = $i; }
- 100000 =
$array = []; for($i=0;$i<100000;$i++) { $array[] = $i; }
$array = []; for($i=0;$i<100000;$i++) { $array[] = $i; }
为了testing,我将使用5.6.29
和7.1.0
5.6.29
容器,如:
sudo docker run -it --rm php:5.6.29-cli php -r '<<<CODE HERE>>>'
上面列出的<<option code>>
,以上列出的testing<<input code>>
的每种组合都将在两个版本的PHP上运行。 对于每个testing运行,使用以下代码片段:
<<input code>> error_reporting(E_ALL); <<option code>> error_reporting(0); $before=microtime(TRUE); for($i=0;$i<100;$i++){echo ".";for($j=0;$j<1;$j++){ <<option code>> }}; $after=microtime(TRUE); echo "\n"; var_dump($x); echo round(($after-$before)*10);
对于每次运行,这将var_dump最后检索到的最后一个testinginput值,并打印一个迭代的平均持续时间( 以纳秒为单位) 。
结果如下:
/=======================================================================================================================================================================================================================================================================================================\ || || TESTINPUT - 5 . 6 . 2 9 || TESTINPUT - 7 . 1 . 0 || || || null | empty | last_null | auto_idx | shuffle | 100 | 100000 || null | empty | last_null | auto_idx | shuffle | 100 | 100000 || ||===========================OPTIONS - ERRORS==========================++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============<| || 1. $x = array_values(array_slice($array, -1))[0]; || W1 + W2 | N1 | - | - | - | - | - || W1 + W2 | N1 | - | - | - | - | - || || 2. $x = array_slice($array, -1)[0]; || W1 | N1 | - | - | - | - | - || W1 | N1 | - | - | - | - | - || || 3. $x = array_pop((array_slice($array, -1))); || W1 + W3 | - | - | - | - | - | - || W1 + N2 + W3 | N2 | N2 | N2 | N2 | N2 | N2 || || 4. $x = array_pop((array_slice($array, -1, 1))); || W1 + W3 | - | - | - | - | - | - || W1 + N2 + W3 | N2 | N2 | N2 | N2 | N2 | N2 || || 5. $x = end($array); reset($array); || W4 + W5 | - | - | - | - | - | - || W4 + W5 | - | - | - | - | - | - || || 6. $x = end((array_values($array))); || W2 + W4 | - | - | - | - | - | - || W2 + N2 + W4 | N2 | N2 | N2 | N2 | N2 | N2 || || 7. $x = $array[count($array)-1]; || - | N3 | - | - | - | - | - || - | N3 | - | - | - | - | - || || 8. $keys = array_keys($array); $x = $array[$keys[count($keys)-1]]; || W5 | N3 + N4 | - | - | - | - | - || W5 | N3 + N4 | - | - | - | - | - || || 9. $x = $array[] = array_pop($array); || W3 | - | - | - | - | - | - || W3 | - | - | - | - | - | - || ||=======================OPTIONS - VALUE RETRIEVED=====================++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============<| || 1. $x = array_values(array_slice($array, -1))[0]; || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(9999999) || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(9999999) || || 2. $x = array_slice($array, -1)[0]; || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(9999999) || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(9999999) || || 3. $x = array_pop((array_slice($array, -1))); || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(9999999) || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(9999999) || || 4. $x = array_pop((array_slice($array, -1, 1))); || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(9999999) || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(9999999) || || 5. $x = end($array); reset($array); || NULL | bool(false) | NULL | string(1) "d" | string(1) "c" | int(99) | int(9999999) || NULL | bool(false) | NULL | string(1) "d" | string(1) "c" | int(99) | int(9999999) || || 6. $x = end((array_values($array))); || NULL | bool(false) | NULL | string(1) "d" | string(1) "c" | int(99) | int(9999999) || NULL | bool(false) | NULL | string(1) "d" | string(1) "c" | int(99) | int(9999999) || || 7. $x = $array[count($array)-1]; || NULL | NULL | NULL | string(1) "d" | string(1) "b" | int(99) | int(9999999) || NULL | NULL | NULL | string(1) "d" | string(1) "b" | int(99) | int(9999999) || || 8. $keys = array_keys($array); $x = $array[$keys[count($keys)-1]]; || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(9999999) || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(9999999) || || 9. $x = $array[] = array_pop($array); || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(9999999) || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(9999999) || ||================OPTIONS - NANOSECONDS PER ITERATION==================++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============<| || 1. $x = array_values(array_slice($array, -1))[0]; || 681 | 413 | 320 | 321 | 317 | 649 | 1.034.200 || 642 | 231 | 102 | 110 | 105 | 174 | 86.700 || || 2. $x = array_slice($array, -1)[0]; || 362 | 301 | 206 | 205 | 202 | 530 | 1.006.000 || 329 | 205 | 63 | 67 | 65 | 134 | 87.000 || || 3. $x = array_pop((array_slice($array, -1))); || 671 | 183 | 273 | 273 | 269 | 597 | 997.200 || 807 | 244 | 282 | 305 | 285 | 355 | 87.300 || || 4. $x = array_pop((array_slice($array, -1, 1))); || 687 | 206 | 303 | 305 | 294 | 625 | 1.003.600 || 812 | 249 | 284 | 288 | 287 | 359 | 87.200 || || 5. $x = end($array); reset($array); || 671 | 136 | 137 | 140 | 137 | 137 | 139 || 632 | 43 | 45 | 46 | 45 | 45 | 45 || || 6. $x = end((array_values($array))); || 674 | 156 | 278 | 278 | 257 | 2.934 | 8.464.000 || 835 | 239 | 270 | 274 | 265 | 474 | 815.000 || || 7. $x = $array[count($array)-1]; || 90 | 257 | 102 | 101 | 101 | 106 | 102 || 31 | 190 | 32 | 34 | 35 | 32 | 32 || || 8. $keys = array_keys($array); $x = $array[$keys[count($keys)-1]]; || 420 | 543 | 365 | 369 | 334 | 3.498 | 12.190.000 || 358 | 373 | 90 | 97 | 89 | 333 | 1.322.000 || || 9. $x = $array[] = array_pop($array); || 145 | 150 | 144 | 144 | 143 | 144 | 143 || 46 | 46 | 46 | 49 | 48 | 46 | 47 || \=======================================================================================================================================================================================================================================================================================================/
上述的编码和编码代码翻译为:
W1 = Warning: array_slice() expects parameter 1 to be array, null given in Command line code on line 1 W2 = Warning: array_values() expects parameter 1 to be array, null given in Command line code on line 1 W3 = Warning: array_pop() expects parameter 1 to be array, null given in Command line code on line 1 W4 = Warning: end() expects parameter 1 to be array, null given in Command line code on line 1 W5 = Warning: reset() expects parameter 1 to be array, null given in Command line code on line 1 W6 = Warning: array_keys() expects parameter 1 to be array, null given in Command line code on line 1 N1 = Notice: Undefined offset: 0 in Command line code on line 1 N2 = Notice: Only variables should be passed by reference in Command line code on line 1 N3 = Notice: Undefined offset: -1 in Command line code on line 1 N4 = Notice: Undefined index: in Command line code on line 1
根据这一结果,我得出以下结论:
- 尽可能使用较新版本的PHP(duh)
- 对于大型arrays,选项仅限于:
- 选项5.
$x = end($array); reset($array);
$x = end($array); reset($array);
- 或选项7.
$x = $array[count($array)-1];
- 或者选项9.
$x = $array[] = array_pop($array);
- 选项5.
- 对于非自动索引的数组,选项7和9不是一个选项
就个人而言,我不喜欢关于自己的数组内部指针,喜欢在单个expression式中的解决scheme。 所以我会用自己的短篇小说:
- 对于自动索引数组:
- 任何选项7.
$x = $array[count($array)-1];
- 或者选项9.
$x = $array[] = array_pop($array);
- 任何选项7.
-
对于非自动索引的数组:(无效)-
选项9.$x = $array[] = array_pop($array);
-
有点取决于是否使用arrays作为堆栈或队列,你可以在选项9上作出变化。
避免传递引用错误的一种方法(例如“end(array_values($ foo))”)是使用call_user_func或者call_user_func_array:
// PHP Fatal error: Only variables can be passed by reference // No output (500 server error) var_dump(end(array(1, 2, 3))); // No errors, but modifies the array's internal pointer // Outputs "int(3)" var_dump(call_user_func('end', array(1, 2, 3))); // PHP Strict standards: Only variables should be passed by reference // Outputs "int(3)" var_dump(end(array_values(array(1, 2, 3)))); // No errors, doesn't change the array // Outputs "int(3)" var_dump(call_user_func('end', array_values(array(1, 2, 3))));
未经testing:这不会工作吗?
<?php $last_element=end(array_values($array)); ?>
由于array_values返回的数组是暂时的,所以没有人关心它的指针是否被重置。
如果你需要钥匙去与它,我想你会做的:
<?php $last_key=end(array_keys($array)); ?>
我经常需要这个来处理堆栈,而且我总是觉得自己很困惑,没有原生函数,没有以某种forms操作数组或内部指针。
所以我通常携带一个在关联数组上使用也是安全的util函数。
function array_last($array) { if (count($array) < 1) return null; $keys = array_keys($array); return $array[$keys[sizeof($keys) - 1]]; }
end()将提供数组的最后一个元素
$array = array('a' => 'a', 'b' => 'b', 'c' => 'c'); echo end($array); //output: c $array1 = array('a', 'b', 'c', 'd'); echo end($array1); //output: d
要获取数组的最后一个元素,请使用:
$lastElement = array_slice($array, -1)[0];
基准
我迭代了1000次,分别抓取了包含100个和50000个元素的大小数组的最后一个元素。
Method: $array[count($array)-1]; Small array (μs): 0.000319957733154 Large array (μs): 0.000526905059814 Note: Fastest! count() must access an internal length property. Note: This method only works if the array is naturally-keyed (0, 1, 2, ...). Method: array_slice($array, -1)[0]; Small array (μs): 0.00145292282104 Large array (μs): 0.499367952347 Method: array_pop((array_slice($array, -1, 1))); Small array (μs): 0.00162816047668 Large array (μs): 0.513121843338 Method: end($array); Small array (μs): 0.0028350353241 Large array (μs): 4.81077480316 Note: Slowest...
我使用PHP版本5.5.32。
为了我:
$last = $array[count($array) - 1];
与协会:
$last =array_values($array)[count($array - 1)]
要做到这一点,避免E_STRICT,而不是混乱的数组的内部指针,你可以使用:
function lelement($array) {return end($array);} $last_element = lelement($array);
元素只能与副本一起工作,所以不会影响数组的指针。
另一个scheme
$array = array('a' => 'a', 'b' => 'b', 'c' => 'c'); $lastItem = $array[(array_keys($array)[(count($array)-1)])]; echo $lastItem;
$lastValue = end(array_values($array))
没有修改$数组指针。 这避免了
reset($array)
这在某些情况下可能是不希望的。
为了从数组中获取最后一个值:
array_slice($arr,-1,1) ;
删除最后一个值表单数组:
array_slice($arr,0,count($arr)-1) ;
简单地说: $last_element = end((array_values($array)))
不重置数组,不给出严格的警告。
PS。 由于大多数投票答案仍然没有双括号,我提交了这个答案。
再一个可能的解决scheme
$last_element = array_reverse( $array )[0];
怎么样:
current(array_slice($array, -1))
- 适用于关联数组
- 当
$array == []
(返回false
) - 不影响原始数组
我认为这是对所有现有答案的轻微改进:
$lastElement = count($array) > 0 ? array_values(array_slice($array, -1))[0] : null;
- 使用
array_keys()
执行比end()
更好的解决scheme,特别是对于大数组 - 不会修改数组的内部指针
- 不会尝试访问空数组未定义的偏移量
- 对于空数组,索引数组,混合数组和关联数组将按预期工作
如果你不关心修改内部指针(同时支持索引和关联数组):
// false if empty array $last = end($array); // null if empty array $last = !empty($array) ? end($array) : null;
如果你想要一个不修改内部指针的工具函数:
function array_last($array) { if (empty($array)) { return null; } return end($value); }
原始数组的内部指针不被修改,因为数组被复制。
因此,下面的select实际上更快,因为它不复制数组,它只是一个片段:
function array_last($array) { if (empty($array)) { return null; } foreach (array_slice($array, -1) as $value) { return $value; } }
这个“foreach / return”是有效获取第一个(这里是单个)项目的一个调整。
最后,最快的select,但只有索引数组:
$last = !empty($array) ? $array[count($array)-1] : null;
如果你想获得它的数组的循环内的数组的最后一个元素?
下面的代码会导致无限循环:
foreach ($array as $item) { $last_element = end($array); reset($array); if ($last_element == $item) { // something useful here } }
非关联数组的解决scheme显然很简单:
$last_element = $array[sizeof ($array) - 1]; foreach ($array as $key => $item) { if ($last_element == $item) { // something useful here } }
在几乎所有使用数组的语言中,你都不能用A [A.size-1]出错。 我不能想到一个基于1的数组的语言(而不是基于零)的例子。