วิธีที่ดีที่สุดในการรับองค์ประกอบสุดท้ายของอาร์เรย์โดยไม่ลบมันคืออะไร


427

ตกลง,

ฉันรู้ทั้งหมด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

11
เชื่อหรือไม่ popping และวางไว้บนเป็นหนึ่งในวิธีที่เร็วที่สุดที่ฉัน benchmarked ทำเช่นนี้ $ = $ Val อาร์เรย์ [] = array_pop ($ อาร์เรย์); echo $ val;
2782001

2
คำถามนี้ทำให้มีตัวเลือกมากมาย เพื่อช่วยให้ตัวเองเลือกฉันไม่เปรียบเทียบตัวเลือกที่โดดเด่นมากที่สุด / ที่แตกต่างกันและร่วมกันผลที่ได้เป็นคำตอบที่แยกต่างหาก (: @ user2782001 แนะนำรายการโปรดของฉันจนถึงในความคิดเห็นด้านบน :) ขอบคุณทุกคนที่มีส่วนร่วม!
Paul van Leeuwen

1
@TheodoreRSmithเมื่อ PHP 7.3 เปิดตัวคุณสามารถพิจารณาทำ ( คำแนะนำนี้โดยโคลน Quasimodo ของ 'คำตอบที่ยอมรับ' (เพื่อประกอบการพิจารณาของคุณ) ...
Paul van Leeuwen

คำตอบ:


175

คำตอบมากมายในหัวข้อนี้นำเสนอเราด้วยตัวเลือกที่แตกต่างกันมากมาย เพื่อให้สามารถเลือกจากพวกเขาฉันต้องเข้าใจพฤติกรรมและประสิทธิภาพของพวกเขา ในคำตอบนี้ฉันจะแบ่งปันผลของฉันกับคุณเทียบกับรุ่น PHP 5.6.38, 7.2.10และ7.3.0RC1( คาดว่า 13 ธันวาคม 2018 )

ตัวเลือกที่<<option code>>ฉันจะทดสอบมีดังนี้:

(ฟังก์ชั่นที่กล่าวถึง: array_key_last , array_keys , array_pop , array_slice , array_values , นับ , สิ้นสุด , การตั้งค่า )

อินพุตทดสอบที่<<input code>>จะรวมกับ:

  • null =$array = null;
  • ที่ว่างเปล่า =$array = [];
  • last_null =$array = ["a","b","c",null];
  • auto_idx =$array = ["a","b","c","d"];
  • สับเปลี่ยน =$array = []; $array[1] = "a"; $array[2] = "b"; $array[0] = "c";
  • 100 =$array = []; for($i=0;$i<100;$i++) { $array[] = $i; }
  • 100000 =$array = []; for($i=0;$i<100000;$i++) { $array[] = $i; }

สำหรับการทดสอบผมจะใช้5.6.38, 7.2.10และ7.3.0RC1 PHP ภาชนะนักเทียบท่าที่ชอบ:

sudo docker run -it --rm php:5.6.38-cli-stretch php -r '<<<CODE HERE>>>'

การรวมกันของดังกล่าวข้างต้นที่ระบุไว้ในแต่ละ<<option code>>และ<<input code>>s จะถูกเรียกใช้ในทุกรุ่นของ PHP สำหรับการทดสอบแต่ละครั้งจะใช้ข้อมูลโค้ดต่อไปนี้:

<<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<100;$j++){  <<option code>>  }}; $after=microtime(TRUE); echo "\n"; var_dump($x); echo round(($after-$before)/(100*100)*1000*1000*1000);

สำหรับการรันแต่ละครั้งจะทำให้ var_dump ค่าสุดท้ายที่ดึงมาล่าสุดของอินพุตการทดสอบและพิมพ์ระยะเวลาเฉลี่ยของการวนซ้ำหนึ่งครั้งใน femtoseconds (0.0000000000000000001th ของวินาที)

ผลลัพธ์มีดังนี้:

/==========================================================================================================================================================================================================================================================================================================================================================================================================================\
||                                                                      ||                            T  E  S  T     I  N  P  U  T     -     5  .  6  .  3  8                            ||                             T  E  S  T     I  N  P  U  T     -     7  .  2  .  1  0                           ||                             T  E  S  T     I  N  P  U  T     -     7  .  3  .  0  R  C  1                     ||
||                                                                      ||          null |         empty |     last_null |      auto_idx |       shuffle |           100 |        100000 ||          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 |             - |             - |             - |             - |             - ||       W1 + W2 |            N1 |             - |             - |             - |             - |             - ||
||  2.  $x = array_slice($array, -1)[0];                                ||            W1 |            N1 |             - |             - |             - |             - |             - ||            W1 |            N1 |             - |             - |             - |             - |             - ||            W1 |            N1 |             - |             - |             - |             - |             - ||
||  3.  $x = array_pop((array_slice($array, -1)));                      ||       W1 + W3 |             - |             - |             - |             - |             - |             - ||  W1 + N2 + W3 |            N2 |            N2 |            N2 |            N2 |            N2 |            N2 ||  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 ||  W1 + N2 + W3 |            N2 |            N2 |            N2 |            N2 |            N2 |            N2 ||
||  5.  $x = end($array); reset($array);                                ||       W4 + W5 |             - |             - |             - |             - |             - |             - ||       W4 + W5 |            N2 |            N2 |            N2 |            N2 |            N2 |            N2 ||       W4 + W5 |             - |             - |             - |             - |             - |             - ||
||  6.  $x = end((array_values($array)));                               ||       W2 + W4 |             - |             - |             - |             - |             - |             - ||  W2 + N2 + W4 |             - |             - |             - |             - |             - |             - ||  W2 + N2 + W4 |            N2 |            N2 |            N2 |            N2 |            N2 |            N2 ||
||  7.  $x = $array[count($array)-1];                                   ||             - |            N3 |             - |             - |             - |             - |             - ||            W7 |            N3 |             - |             - |             - |             - |             - ||            W7 |            N3 |             - |             - |             - |             - |             - ||
||  8.  $keys = array_keys($array); $x = $array[$keys[count($keys)-1]]; ||            W6 |       N3 + N4 |             - |             - |             - |             - |             - ||       W6 + W7 |       N3 + N4 |             - |             - |             - |             - |             - ||       W6 + W7 |       N3 + N4 |             - |             - |             - |             - |             - ||
||  9.  $x = $array[] = array_pop($array);                              ||            W3 |             - |             - |             - |             - |             - |             - ||            W3 |             - |             - |             - |             - |             - |             - ||            W3 |             - |             - |             - |             - |             - |             - ||
|| 10.  $x = $array[array_key_last($array)];                            ||            F1 |            F1 |            F1 |            F1 |            F1 |            F1 |            F1 ||            F2 |            F2 |            F2 |            F2 |            F2 |            F2 |            F2 ||            W8 |            N4 |            F2 |            F2 |            F2 |            F2 |            F2 ||
||========================OPTIONS - VALUE RETRIEVED=====================++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============<|
||  1.  $x = array_values(array_slice($array, -1))[0];                  ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||
||  2.  $x = array_slice($array, -1)[0];                                ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||
||  3.  $x = array_pop((array_slice($array, -1)));                      ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||
||  4.  $x = array_pop((array_slice($array, -1, 1)));                   ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||
||  5.  $x = end($array); reset($array);                                ||          NULL |   bool(false) |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |   bool(false) |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |   bool(false) |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||
||  6.  $x = end((array_values($array)));                               ||          NULL |   bool(false) |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |   bool(false) |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |   bool(false) |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||
||  7.  $x = $array[count($array)-1];                                   ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "b" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "b" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "b" |       int(99) |    int(99999) ||
||  8.  $keys = array_keys($array); $x = $array[$keys[count($keys)-1]]; ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||
||  9.  $x = $array[] = array_pop($array);                              ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||
|| 10.  $x = $array[array_key_last($array)];                            ||           N/A |           N/A |           N/A |           N/A |           N/A |           N/A |           N/A ||           N/A |           N/A |           N/A |           N/A |           N/A |           N/A |           N/A ||           N/A |           N/A |           N/A |           N/A |           N/A |           N/A |           N/A ||
||=================OPTIONS - FEMTOSECONDS PER ITERATION=================++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============<|
||  1.  $x = array_values(array_slice($array, -1))[0];                  ||           803 |           466 |           390 |           384 |           373 |           764 |     1.046.642 ||           691 |           252 |           101 |           128 |            93 |           170 |        89.028 ||           695 |           235 |            90 |            97 |            95 |           188 |        87.991 ||
||  2.  $x = array_slice($array, -1)[0];                                ||           414 |           349 |           252 |           248 |           246 |           604 |     1.038.074 ||           373 |           249 |            85 |            91 |            90 |           164 |        90.750 ||           367 |           224 |            78 |            85 |            80 |           155 |        86.141 ||
||  3.  $x = array_pop((array_slice($array, -1)));                      ||           724 |           228 |           323 |           318 |           350 |           673 |     1.042.263 ||           988 |           285 |           309 |           317 |           331 |           401 |        88.363 ||           877 |           266 |           298 |           300 |           326 |           403 |        87.279 ||
||  4.  $x = array_pop((array_slice($array, -1, 1)));                   ||           734 |           266 |           358 |           356 |           349 |           699 |     1.050.101 ||           887 |           288 |           316 |           322 |           314 |           408 |        88.402 ||           935 |           268 |           335 |           315 |           313 |           403 |        86.445 ||
||  5.  $x = end($array); reset($array);                                ||           715 |           186 |           185 |           180 |           176 |           185 |           172 ||           674 |            73 |            69 |            70 |            66 |            65 |            70 ||           693 |            65 |            85 |            74 |            68 |            70 |            69 ||
||  6.  $x = end((array_values($array)));                               ||           877 |           205 |           320 |           337 |           304 |         2.901 |     7.921.860 ||           948 |           300 |           336 |           308 |           309 |           509 |    29.696.951 ||           946 |           262 |           301 |           309 |           302 |           499 |    29.234.928 ||
||  7.  $x = $array[count($array)-1];                                   ||           123 |           300 |           137 |           139 |           143 |           140 |           144 ||           312 |           218 |            48 |            53 |            45 |            47 |            51 ||           296 |           217 |            46 |            44 |            53 |            53 |            55 ||
||  8.  $keys = array_keys($array); $x = $array[$keys[count($keys)-1]]; ||           494 |           593 |           418 |           435 |           399 |         3.873 |    12.199.450 ||           665 |           407 |           103 |           109 |           114 |           431 |    30.053.730 ||           647 |           445 |            91 |            95 |            96 |           419 |    30.718.586 ||
||  9.  $x = $array[] = array_pop($array);                              ||           186 |           178 |           175 |           188 |           180 |           181 |           186 ||            83 |            78 |            75 |            71 |            74 |            69 |            83 ||            71 |            64 |            70 |            64 |            68 |            69 |            81 ||
|| 10.  $x = $array[array_key_last($array)];                            ||           N/A |           N/A |           N/A |           N/A |           N/A |           N/A |           N/A ||           N/A |           N/A |           N/A |           N/A |           N/A |           N/A |           N/A ||           370 |           223 |            49 |            52 |            61 |            57 |            52 ||
 \=========================================================================================================================================================================================================================================================================================================================================================================================================================/ 

ดังกล่าวข้างต้นF atal, W arning และN otice รหัสแปลเป็น:

F1 = Fatal error: Call to undefined function array_key_last() in Command line code on line 1
F2 = Fatal error: Uncaught Error: Call to undefined function array_key_last() in Command line code:1
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
W7 = Warning: count(): Parameter must be an array or an object that implements Countable in Command line code on line 1
W8 = Warning: array_key_last() 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 เวอร์ชันใหม่กว่าทำงานได้ดีขึ้นยกเว้นตัวเลือกเหล่านี้ซึ่งช้าลงอย่างมาก:
    • ตัวเลือก. 6 $x = end((array_values($array)));
    • ตัวเลือก. 8 $keys = array_keys($array); $x = $array[$keys[count($keys)-1]];
  • ตัวเลือกเหล่านี้ปรับขนาดได้ดีที่สุดสำหรับอาร์เรย์ขนาดใหญ่มาก:
    • ตัวเลือก 0.5 $x = end($array); reset($array);
    • ตัวเลือก. 7 $x = $array[count($array)-1];
    • ตัวเลือก. 9 $x = $array[] = array_pop($array);
    • ตัวเลือก 10 $x = $array[array_key_last($array)]; (ตั้งแต่ PHP 7.3)
  • ตัวเลือกเหล่านี้ควรใช้สำหรับอาร์เรย์ที่ทำดัชนีโดยอัตโนมัติเท่านั้น :
    • ตัวเลือก. 7 $x = $array[count($array)-1];(เนื่องจากการใช้งานcount)
    • ตัวเลือก. 9 $x = $array[] = array_pop($array);(เนื่องจากการกำหนดค่าการสูญเสียรหัสเดิม)
  • ตัวเลือกนี้จะไม่รักษาตัวชี้ภายในของอาร์เรย์
    • ตัวเลือก 0.5 $x = end($array); reset($array);
  • ตัวเลือกนี้เป็นความพยายามที่จะแก้ไขตัวเลือก 0.5 เพื่อรักษาตัวชี้ภายในของอาร์เรย์ (แต่น่าเสียดายที่มันไม่ได้ปรับขนาดได้ดีสำหรับอาร์เรย์ขนาดใหญ่มาก)
    • ตัวเลือก. 6 $x = end((array_values($array)));
  • array_key_lastฟังก์ชั่นใหม่ดูเหมือนว่าจะไม่มีข้อ จำกัด ดังกล่าวข้างต้นยกเว้นการยังคงเป็น RC ในช่วงเวลาของการเขียนนี้ (ดังนั้นให้ใช้ RC หรือรอการเปิดตัวในเดือนธันวาคม 2018):
    • ตัวเลือก 10 $x = $array[array_key_last($array)]; (ตั้งแต่ PHP 7.3)

ขึ้นอยู่กับว่าใช้อาร์เรย์เป็นสแต็กหรือเป็นคิวคุณสามารถสร้างรูปแบบตัวเลือกที่ 9


หากคุณพบตัวเลือกเฉพาะที่ขาดหายไปคุณสามารถทดสอบด้วยตัวเองโดยการคัดลอกตัวอย่างโค้ดข้างต้นพร้อมกันเปรียบเทียบกับตัวเลือกที่ผ่านการทดสอบก่อนหน้านี้ ในการเพิ่มตัวเลือกในรายการนี้จะเป็นการทดสอบซ้ำชุดค่าผสมทั้งหมดเพื่อเปรียบเทียบประสิทธิภาพ หากคุณมีตัวเลือกเฉพาะที่คุณคิดว่าควรจะเพิ่มโปรดทิ้งความคิดเห็นไว้ฉันตั้งใจจะเพิ่มมัน (แม้ว่าอาจใช้เวลาสักครู่)
Paul van Leeuwen

1
คำตอบที่ดีมาก แต่มีความคิดเห็นหนึ่งข้อสำหรับตัวเลือกอาเรย์แบบเชื่อมโยง 9 ไม่สามารถใช้ได้เช่นกันเพราะเรากำลังกำหนดกลับไปที่คีย์ทำดัชนีอัตโนมัติแทนชื่อคีย์ก่อนหน้า
Gras Double

1
สรุปดี! โปรดเพิ่มคำตอบของฉันโดยใช้ PHP 7.3 ใหม่ ฟังก์ชั่น$array[array_key_last($array)];มาตรฐานของคุณ และโปรดแจ้งให้ฉันทราบเมื่อเสร็จแล้ว ฉันต้องการดูผลการเปรียบเทียบ
โคลนของ Quasimodo

2
@sz ส่วนใหญ่ผลิตด้วยความดื้อรั้นและความอดทน แต่การเลือกทั่วไปและฟังก์ชั่นแก้ไขหลายบรรทัดของ Sublime text editor ช่วย การสร้างใหม่ใช้เวลาเกือบวันดังนั้นถ้าฉันต้องทำอีกครั้งฉันอาจจะเขียนอะไรบางอย่างที่แปลงผลลัพธ์ของการประหารชีวิตนักเทียบท่า 210 คนให้เป็นตารางโดยอัตโนมัติ :-)
Paul van Leeuwen

1
@ quasimodos-clone ฉันสร้างตารางทั้งหมดตาม PHP 5, 7 และ RC ของคุณ ฉันคิดว่าเราจะต้องการสร้างมันอีกครั้งในเดือนธันวาคมที่จะถึงนี้เมื่อมีการเปิดตัวจริง ขอบคุณที่นำฟังก์ชั่นใหม่นี้ให้ทุกคนสนใจ
Paul van Leeuwen

487

ลอง

$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 และทุกคน!


38
การใช้งานและตอนนี้คุณไม่จำเป็นต้องโทร$myLastElement = end(array_values($yourArray)); reset()
David Murdoch

5
@DavidMurdoch บางที แต่ก็แน่ใจว่าจะปั่น RAM และ CPU สร้างอาร์เรย์ temp สำหรับค่าอาร์เรย์ ...
Theodore R. Smith

12
หากเซิร์ฟเวอร์ของคุณใช้ RAM มากเกินไปเพื่อให้การเรียกฟังก์ชั่นพิเศษง่ายๆอย่างหนึ่งคือตัวจัดการข้อตกลงฉันขอแนะนำให้คุณตรวจสอบการกำหนดค่าและทรัพยากรของเซิร์ฟเวอร์อีกครั้ง
Chris Baker

3
end(array_values())จะให้ E_STRICT ว่า "ตัวแปรเฉพาะควรจะผ่านอ้างอิง"
kolypto

32
เพิ่มวงเล็บเพิ่มเติมเพื่อหลีกเลี่ยงคำเตือนที่เข้มงวด: end((array_values($yourArray)))
Daniel W.

212

สั้นและหวาน

ฉันหาวิธีแก้ปัญหาเพื่อลบข้อความแสดงข้อผิดพลาดและรักษารูปแบบซับในหนึ่งอันและประสิทธิภาพที่มีประสิทธิภาพ:

$lastEl = array_values(array_slice($array, -1))[0];

- ทางออกก่อนหน้า

$lastEl = array_pop((array_slice($array, -1)));

หมายเหตุ: PHP Strict standards: Only variables should be passed by referenceวงเล็บพิเศษที่มีความจำเป็นที่จะหลีกเลี่ยง


31
หลังจาก 5 ปี 6 เดือนและ 2 วันคุณได้ส่งคำตอบที่ดีกว่า !! ขอบคุณ! และขอบคุณกองมากล้น !!
Theodore R. Smith

1
สวัสดีคำตอบ แต่การเพิ่มเครื่องหมายวงเล็บพิเศษให้ความรู้สึกเล็กน้อย นอกจากนี้ phpStorm จะทำเครื่องหมายว่านี่เป็นข้อผิดพลาด ข้อมูลเพิ่มเติมสำหรับการเพิ่มวงเล็บพิเศษ ( phpsadness.com/sad/51 ) เพื่อเอาชนะข้อผิดพลาดคุณสามารถทำให้ '2-liner': โดย$array = array_slice($array, -1); $lastEl = array_pop($array);ส่วนตัวแล้วฉันคิดว่ามันดีกว่า (โดยไม่มีตัวแยกวิเคราะห์ 'bug)
Maurice

3
คุณสามารถใช้การยกเลิกการลงทะเบียนเช่นนี้: array_slice ($ array, -1) [0]
Vikash

1
คุณทำไม่ได้ถ้าคุณมีสตริงเป็นดัชนีในอาร์เรย์
rolacja

3
คำตอบนี้ยังต้องการการตรวจสอบอย่างน้อยสองครั้งเพื่อหลีกเลี่ยงการแจ้งเตือน PHP 1.ตรวจสอบว่าarray_size() > 1 2.ตรวจสอบว่าอาร์เรย์เป็นอาร์เรย์จริงหรือไม่ ฉันยังคงยึดถือคำตอบของ @Iznogood เนื่องจากend()ฟังก์ชั่นการใช้งานของ PHP นั้นทำงานอย่างมีประสิทธิภาพมากขึ้นแล้ว
Ema4rl

37

มีอะไรผิดปกติกับarray_slice($array, -1)? (ดูคู่มือ: http://us1.php.net/array_slice )

array_slice()ส่งกลับอาร์เรย์ อาจไม่ใช่สิ่งที่คุณกำลังมองหา คุณต้องการองค์ประกอบ


21
ใช้array_slice($array, -1)[0]เพื่อรับองค์ประกอบ
ปาง

2
นี่คือคำตอบ "สิ้นสุด" การเปลี่ยนตัวชี้ภายในของอาร์เรย์หรือไม่ ถามหาปัญหาและอ่านยากมาก!
เจอราร์ดโอนีล

รักวิธีการนี้แม้ว่า @Pang จะชี้ให้เห็นว่ายังไม่สมบูรณ์ reset(array_slice($array, -1))เป็นวิธีการอื่น (ที่จะไม่ทำให้เกิดข้อผิดพลาดหากarray_slice()ส่งคืน "เล็ก" กว่าอาร์เรย์องค์ประกอบเดียว)
rinogo

วิธีการที่ดีที่สุดในขณะที่คุณสามารถปรับเปลี่ยนองค์ประกอบได้โดยตรง:array_slice($array, -1)[0] = "";
HAlex

20

วิธีหนึ่งในการหลีกเลี่ยงข้อผิดพลาดแบบอ้างอิงอ้างอิง (เช่น "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))));

วิธีการที่ยอดเยี่ยม! (แทรกมาตรฐาน 'นี่ควรเป็นคำตอบที่ยอมรับได้' ที่นี่)
Typo

3
หรือเพียงแค่เพิ่มคำจำกัดความพิเศษ สั้นและหวาน:end((array_values($yourArray)))
Dzhuneyt

4
เคล็ดลับวงเล็บเพิ่มเติมอาศัยข้อผิดพลาดใน PHP และวิธีการดังกล่าวไม่สามารถใช้งานได้ใน PHP รุ่นใหม่กว่า (หรืออย่างน้อยไม่ใช่ PHP 7)
Matt Browne

1
และcall_user_funcเคล็ดลับไม่ทำงานใน PHP 7 เช่นกัน ฉันคิดว่าคุณติดอยู่กับการสร้างตัวแปรชั่วคราว
Matt Browne

15

หากคุณไม่สนใจเกี่ยวกับการแก้ไขตัวชี้ภายใน (รองรับทั้งอาร์เรย์ที่จัดทำดัชนีและเชื่อมโยง):

// 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($array);
}

โปรดทราบว่า PHP สร้างสำเนา "on-the-fly" เช่นเมื่อจำเป็นจริงๆเท่านั้น end()ตัวเองปรับเปลี่ยนอาร์เรย์ดังนั้นภายในสำเนาของอาร์เรย์จะถูกสร้างขึ้น


ดังนั้นทางเลือกต่อไปนี้จะเร็วขึ้นจริง ๆ เพราะภายในไม่ได้คัดลอกอาเรย์มันแค่สร้างส่วนแบ่ง:

function array_last($array) {
    if (empty($array)) {
        return null;
    }
    foreach (array_slice($array, -1) as $value) {
        return $value;
    }
}

"foreach / return" นี้เป็นการปรับแต่งเพื่อให้ได้ไอเท็มแรก (และที่นี่เดี่ยว) อย่างมีประสิทธิภาพ


ในที่สุดทางเลือกที่เร็วที่สุด แต่สำหรับอาร์เรย์ที่ทำดัชนีเท่านั้น:

$last = !empty($array) ? $array[count($array)-1] : null;



สำหรับบันทึกนี่คือคำตอบของฉันอีกประการหนึ่งสำหรับองค์ประกอบแรกของอาร์เรย์


คุณให้การใช้งานทางเลือก 2 ทางสำหรับarray_lastฟังก์ชั่น สำหรับครั้งแรกที่คุณระบุว่า$arrayมีการคัดลอกและครั้งที่สองที่ไม่ได้คัดลอก ความแตกต่าง / ทำไมมันถูกคัดลอกในการใช้งานครั้งแรกและไม่ได้อยู่ในที่สอง?
Paul van Leeuwen

1
@PaulvanLeeuwen ฉันเข้าใจว่าทำไมคุณถึงสับสน ฉันพยายามชี้แจงคำตอบให้ดีขึ้นไหม?
Gras Double

10

ยังไม่ทดลอง: ใช้งานไม่ได้หรือ

<?php
$last_element=end(array_values($array));
?>

เนื่องจากอาร์เรย์ที่ส่งคืนโดย array_values ​​กำลังหายไปไม่มีใครสนใจหากตัวชี้นั้นถูกรีเซ็ต

และถ้าคุณต้องการกุญแจที่จะไปกับมันฉันเดาว่าคุณจะทำ:

<?php
$last_key=end(array_keys($array));
?>

9

ฉันต้องการสิ่งนี้บ่อยครั้งเพื่อจัดการกับสแต็คและฉันมักจะพบว่าตัวเองงงงันว่าไม่มีฟังก์ชั่นพื้นเมืองที่ทำโดยไม่ต้องจัดการอาร์เรย์หรือตัวชี้ภายในของมันในบางรูปแบบ

ดังนั้นฉันมักจะพกพาฟังก์ชั่น util ที่ปลอดภัยที่จะใช้ในอาเรย์แบบเชื่อมโยง

function array_last($array) {
    if (count($array) < 1)
        return null;

    $keys = array_keys($array);
    return $array[$keys[sizeof($keys) - 1]];
}

1
ข่าวดีพวกเขาทำให้มันเป็นฟังก์ชั่นดั้งเดิม :-) คุณสามารถจับตาการวางแผนปล่อยได้ที่นี่: wiki.php.net/todo/php73 (คาดว่าจะถึงวันที่ 13 ธันวาคม 2018 ในขณะที่เขียนนี้)
Paul van Leeuwen

9

ในการรับองค์ประกอบสุดท้ายของอาร์เรย์ให้ใช้:

$lastElement = array_slice($array, -1)[0];

เกณฑ์มาตรฐาน

ฉันทำซ้ำ 1,000 ครั้งคว้าองค์ประกอบสุดท้ายของอาร์เรย์ขนาดเล็กและขนาดใหญ่ที่มีองค์ประกอบ 100 และ 50,000 ตามลำดับ

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


แล้วการใช้ $ array [array_keys ($ array) [count (array_keys ($ array)) - 1]]?
user2782001

อืม ..array_keys ดูเหมือนจะขยายตัวค่อนข้างแย่
user2782001

1
จริง ๆ แล้วมันบ้าเร็วกว่าสำหรับอาร์เรย์ขนาดใหญ่ (0.0002) เพื่อป๊อปไอเท็มและวางกลับบน ... $ val = $ ar [] = $ array_pop ($ ar);
user2782001

1
@ Westy92 หน่วยงานของคุณดูผิดไปจากเกณฑ์มาตรฐาน จำนวนที่น้อยที่สุดที่คุณให้คือ 0.00031 ... ไมโครวินาทีซึ่งประมาณ 0.3 นาโนวินาที นั่นหมายความว่าการทดสอบของคุณใช้สัญญาณนาฬิกาหนึ่งขีดเพื่อเรียกใช้ถ้าคุณมีคอมพิวเตอร์ใหม่ ฉันคาดเดาคุณหมายถึงทั้งมิลลิวินาทีหรืออาจเป็นไปได้ไม่กี่วินาที
cesoid

1
ค่าต่าง ๆ มีขนาดของคำสั่งผิดอย่างชัดเจน ทำไมต้องเน้นเรื่องประสิทธิภาพอยู่ดี
istepaniuk

6

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

1
วิธีนี้ใช้ได้ผล แต่มันเปลี่ยนตัวชี้ภายในของอาเรย์ฉันไม่คิดว่ามันเป็นวิธีที่ถูกต้อง
UnixAgain

5

ในฐานะที่เป็นรุ่น PHP 7.3 ฟังก์ชั่นarray_key_firstและarray_key_lastได้รับการแนะนำ

เนื่องจากอาร์เรย์ใน PHP ไม่ใช่ประเภทอาเรย์ที่เข้มงวดเช่นคอลเลกชันขนาดคงที่ของฟิลด์ที่มีขนาดคงที่เริ่มต้นที่ดัชนี 0 แต่อาเรย์แบบขยายที่สัมพันธ์กันแบบไดนามิกการจัดการตำแหน่งด้วยคีย์ที่ไม่รู้จักนั้นทำได้ยาก ในทางตรงกันข้ามอาร์เรย์ที่แท้จริงจะได้รับการแก้ไขภายในผ่านพอยต์เลขคณิตของตัวชี้อย่างรวดเร็วและดัชนีสุดท้ายเป็นที่รู้จักกันแล้วในเวลารวบรวมโดยการประกาศ

อย่างน้อยปัญหาเกี่ยวกับตำแหน่งแรกและตำแหน่งสุดท้ายจะถูกแก้ไขโดยฟังก์ชัน builtin ตั้งแต่เวอร์ชัน 7.3 สิ่งนี้สามารถใช้งานได้โดยไม่มีการเตือนใด ๆ เกี่ยวกับตัวอักษรของอาร์เรย์ :

$first = array_key_first( [1, 2, 'A'=>65, 'B'=>66, 3, 4 ] );
$last  = array_key_last ( [1, 2, 'A'=>65, 'B'=>66, 3, 4 ] );

เห็นได้ชัดว่าค่าสุดท้ายคือ:

$array[array_key_last($array)];

1
ขอขอบคุณที่แจ้งเรื่องนี้ให้ทุกคนทราบ สำหรับผู้ที่มีความกระตือรือร้นที่จะใช้สิ่งนี้โปรดอย่าว่านี่คือ RC ในขณะที่เขียนนี้ มีกำหนดการวางจำหน่ายในเดือนธันวาคม 2018
Paul van Leeuwen

1
นี่เป็นข่าวดี ฉันเพิ่งโพลีฟิล / ชิมในคำตอบของฉันด้านล่างเพื่อให้ผู้คนสามารถเริ่มใช้ไวยากรณ์นี้ได้ทันที
Mark Thomson

3
$lastValue = end(array_values($array))

ไม่มีการแก้ไขตัวชี้ $ array สิ่งนี้หลีกเลี่ยง

reset($array)

ซึ่งอาจไม่ต้องการในบางเงื่อนไข


3

สำหรับฉัน:

$last = $array[count($array) - 1];

กับสมาคม:

$last =array_values($array)[count($array - 1)]

โปรดระบุบริบทให้กับคำตอบของคุณ
Shawn

2
@Shawn บริบทใด ไม่ต้องการบริบท เพิ่มรหัสสำหรับอาเรย์แบบเชื่อมโยง
Mirko Pagliai

3

คำตอบด้านบนที่ดี แต่ดังกล่าวโดย @ Paul-รถตู้ Leeuwen และ @ quasimodos โคลน, PHP 7.3 จะแนะนำสองฟังก์ชั่นใหม่ที่จะแก้ปัญหานี้โดยตรง - array_key_first ()และarray_key_last ()

คุณสามารถเริ่มใช้ไวยากรณ์นี้วันนี้ด้วยฟังก์ชัน polyfill (หรือชิม) ต่อไปนี้

// Polyfill for array_key_last() available from PHP 7.3
if (!function_exists('array_key_last')) {
  function array_key_last($array) {
    return array_slice(array_keys($array),-1)[0];
  }
}

// Polyfill for array_key_first() available from PHP 7.3
if (!function_exists('array_key_first')) {
  function array_key_first($array) {
    return array_slice(array_keys($array),0)[0];
  }
}

// Usage examples:
$first_element_key   = array_key_first($array);
$first_element_value = $array[array_key_first($array)];

$last_element_key    = array_key_last($array);
$last_element_value  = $array[array_key_last($array)];

Caveat: ต้องใช้ PHP 5.4 ขึ้นไป


2

ในการทำเช่นนี้และหลีกเลี่ยง E_STRICT และไม่ยุ่งกับตัวชี้ภายในของอาร์เรย์คุณสามารถใช้:

function lelement($array) {return end($array);}

$last_element = lelement($array);

lelement ใช้ได้กับสำเนาเท่านั้นจึงไม่ส่งผลกระทบต่อตัวชี้ของอาร์เรย์



2

อีกวิธีหนึ่งที่เป็นไปได้ ...

$last_element = array_reverse( $array )[0];

ไม่ทำงานในอาเรย์แบบเชื่อมโยงดูเหมือนจะไม่มีเหตุผลเพียงพอที่จะลงคะแนนให้ฉัน คำตอบนี้ไม่ได้แย่ไปกว่าคุณภาพแล้วคำตอบอื่น ๆ อีกมากมายสำหรับคำถามนี้ ฉันไม่เข้าใจว่าทำไมฉันเห็น downvotes อย่างน้อย 2 ตัวในเวลานี้ (คะแนน -2) เอาล่ะโหวตขึ้นสำหรับฉันมันไม่ได้เลวร้าย
Paul van Leeuwen

2

เกี่ยวกับ:

current(array_slice($array, -1))
  • ใช้ได้กับอาร์เรย์ที่เชื่อมโยงกัน
  • ทำงานเมื่อ$array == [](ส่งคืนfalse)
  • ไม่ส่งผลกระทบต่ออาร์เรย์เดิม

2

คุณจะได้รับองค์ประกอบสุดท้ายจากอาร์เรย์ได้อย่างง่ายดายโดยใช้ตรรกะด้านล่าง

$array = array('a', 'b', 'c', 'd');
echo ($array[count($array)-1]);

ไม่เพียง แต่องค์ประกอบสุดท้ายเท่านั้น แต่คุณยังสามารถได้อันดับสองที่สามที่ผ่านมาและต่อไปโดยใช้ตรรกะด้านล่าง

สำหรับองค์ประกอบสุดท้ายที่สองคุณต้องผ่านเพียงหมายเลข 2 ในคำสั่งด้านบนตัวอย่างเช่น:
echo ($ array [count ($ array) -2]);


1

สำหรับการรับค่าสุดท้ายจาก Array:

array_slice($arr,-1,1) ;

สำหรับการลบอาร์เรย์ของฟอร์มค่าสุดท้าย:

array_slice($arr,0,count($arr)-1) ;

1
array_slice($arr,-1,1)จะส่งผลให้อาร์เรย์มีความยาว 1 ไม่ใช่องค์ประกอบสุดท้าย
Vic

ลองมาตัวอย่าง: $a=array("red","green","blue","yellow","brown"); print_r(array_slice($a,-1,1)); ผล:Array ( [0] => brown )
Rishabh

1

เพียง: $last_element = end((array_values($array)))

ไม่รีเซ็ตอาร์เรย์และไม่ให้คำเตือนที่เข้มงวด

PS เนื่องจากคำตอบที่ได้รับการโหวตมากที่สุดยังไม่เป็นวงเล็บคู่ฉันจึงส่งคำตอบนี้


1

ฉันคิดว่านี่เป็นการปรับปรุงเล็กน้อยสำหรับคำตอบที่มีอยู่ทั้งหมด:

$lastElement = count($array) > 0 ? array_values(array_slice($array, -1))[0] : null;
  • ทำงานได้ดีกว่าend()หรือใช้วิธีแก้ปัญหาarray_keys()เฉพาะกับอาร์เรย์ขนาดใหญ่
  • จะไม่แก้ไขตัวชี้ภายในของอาร์เรย์
  • จะไม่พยายามเข้าถึงออฟเซตที่ไม่ได้กำหนดสำหรับอาร์เรย์ที่ว่างเปล่า
  • จะทำงานได้ตามที่คาดไว้สำหรับอาร์เรย์ที่ว่างเปล่าอาร์เรย์ที่จัดทำดัชนีอาร์เรย์แบบผสมและอาร์เรย์ที่เชื่อมโยงกัน

น่าเศร้าที่มันไม่ทำงานกับอาเรย์แบบเชื่อมโยงเพราะไอเท็มชิ้นเดียวของชิ้นอาจมีคีย์ที่มีชื่อ
Gras Double

คุณถูกแก้ไขเพื่อเพิ่มการแก้ไข ( array_valuesในชิ้นองค์ประกอบเดียว)
Adelmar

1

ใช้ฟังก์ชั่น end ()

$array = [1,2,3,4,5];
$last = end($array); // 5

1
เพียงแค่ให้ความสนใจว่าฟังก์ชั่นนี้จะย้ายตัวชี้ของอาร์เรย์ไปยังตำแหน่งนั้น
giovannipds

ยังให้ความสนใจว่านี่โพสต์เป็นคำตอบเมื่อ 8 ปีก่อน stackoverflow.com/a/3687368/1255289
miken32

1

ปัจจุบันฉันชอบเสมอมีผู้ช่วยที่นี้เป็นข้อเสนอแนะที่คำตอบ php.net/end

<?php
function endc($array) {
    return end($array);
}

$items = array('one','two','three');
$lastItem = endc($items); // three
$current = current($items); // one
?>

สิ่งนี้จะรักษาตัวชี้ไว้เสมอและเราจะไม่ต้องกังวลเกี่ยวกับวงเล็บมาตรฐานที่เข้มงวดหรืออะไรก็ตาม


กล่าวถึงแล้วข้างต้น: stackoverflow.com/a/45333947/1255289
miken32

0

หมายเหตุ: สำหรับ (PHP 7> = 7.3.0) เราสามารถใช้ array_key_last - รับคีย์สุดท้ายของอาร์เรย์

array_key_last ( array $array ) : mixed

Ref: http://php.net/manual/th/function.array-key-last.php


1
คำตอบนี้มีหลายคำตอบอยู่แล้ว
miken32

แต่ฉันตอบก่อนหน้านี้กว่าคนอื่น ๆ
lokender singh

-1

ถ้าคุณต้องการที่จะได้รับองค์ประกอบสุดท้ายของอาร์เรย์ภายในวงของมันคืออะไร?

โค้ดด้านล่างจะส่งผลให้วงวนไม่สิ้นสุด:

foreach ($array as $item) {
 $last_element = end($array);
 reset($array);
 if ($last_element == $item) {
   // something useful here
 }
}

เห็นได้ชัดว่าวิธีแก้ปัญหานั้นง่ายสำหรับอาเรย์แบบไม่เชื่อมโยง:

$last_element = $array[sizeof ($array) - 1];
foreach ($array as $key => $item) {
 if ($last_element == $item) {
   // something useful here
 }
}

2
ฉันรู้เกี่ยวกับฟังก์ชั่น end () และ reset () ความคิดเห็นของฉันเกี่ยวข้องกับลูปเช่น foreach หรือในขณะที่คุณไม่สามารถใช้ฟังก์ชันเหล่านี้ได้เนื่องจากฟังก์ชันรีเซ็ตรีเซ็ตตัวชี้ภายในของอาร์เรย์ที่ใช้ในการวนซ้ำสำหรับการวนซ้ำ ขออภัยสำหรับคำถามนั้นง่ายขึ้นฉันแค่ต้องการให้สถานการณ์ขั้นสูงเพิ่มเติมที่ฉันเจอในโครงการของฉัน ขอแสดงความนับถืออย่างสูง.
Vadim Podlevsky

สิ่งนี้ผิดในหลายวิธี (อาร์เรย์ที่มีการซ้ำซ้อนการเปรียบเทียบที่ไม่เข้มงวด ... ) และในกรณีใด ๆ ที่ไม่เกี่ยวข้องกับคำถามจริงๆ
Tgr

ใช้ฟังก์ชัน end ($ array) เพื่อรับองค์ประกอบสุดท้ายทำไมคุณใช้ลูปโดยไม่จำเป็น?
Mahak Choudhary

1
@MahakChoudhary ความคิดเห็นของฉันคือการเพิ่ม "วิธีการรับองค์ประกอบสุดท้ายของอาร์เรย์ถ้าคุณกำลังทำกิจวัตรบางอย่างแล้วในวงของอาร์เรย์นี้การใช้ end () จะรีเซ็ตตัวชี้ Innver และทำลายวนการวนซ้ำไชโย!
Vadim Podlevsky

-1
$file_name_dm =  $_FILES["video"]["name"];    

                           $ext_thumb = extension($file_name_dm);

                            echo extension($file_name_dm); 
function extension($str){
    $str=implode("",explode("\\",$str));
    $str=explode(".",$str);
    $str=strtolower(end($str));
     return $str;
}


-1

ง่ายมาก

$array = array('a', 'b', 'c', 'd');
end($array)

มันจะพูดถึงว่านี่มีพฤติกรรมที่แปลกถ้าคุณใช้อาร์เรย์ที่มีช่องว่าง เช่น$a = array(); $a[2] = 'c'; $a[1] = 'b'; echo end($a); จะกลับมาb
Simon Zyx

โพสต์นี้เมื่อ 9 ปีที่แล้ว stackoverflow.com/a/3687368/1255289
miken32

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.