获取数组的最后一个元素而不删除它的最好方法是什么?

好,

我知道所有关于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.297.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.297.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);
  • 对于非自动索引的数组,选项7和9不是一个选项

就个人而言,我不喜欢关于自己的数组内部指针,喜欢在单个expression式中的解决scheme。 所以我会用自己的短篇小说:

  • 对于自动索引数组:
    • 任何选项7. $x = $array[count($array)-1];
    • 或者选项9. $x = $array[] = array_pop($array);
  • 对于非自动索引的数组:(无效)
    • 选项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的数组的语言(而不是基于零)的例子。