วิธีรับคีย์สุดท้ายในอาเรย์


335

ฉันจะรับคีย์สุดท้ายของอาร์เรย์ได้อย่างไร


10
ควรระบุอาเรย์แบบเชื่อมโยงอาเรย์ตัวเลขหรือถ้าต้องใช้ทั้งคู่
Jimbo Jonny

คำถามที่พบบ่อย
Josua Marcel Chrisano

คำตอบ:


610

วิธีแก้ปัญหาคือการใช้การรวมกันของ(endและการอ้างอิง) :key

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

ดังนั้นส่วนของรหัสเช่นนี้ควรทำเคล็ดลับ:

$array = array(
    'first' => 123,
    'second' => 456,
    'last' => 789, 
);

end($array);         // move the internal pointer to the end of the array
$key = key($array);  // fetches the key of the element pointed to by the internal pointer

var_dump($key);

จะส่งออก:

string 'last' (length=4)

เช่นกุญแจสำคัญขององค์ประกอบสุดท้ายของอาร์เรย์ของฉัน

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


17
@ พิม: ขึ้นอยู่กับสิ่งที่ OP ต้องการทำกับอาเรย์นั้นหลังจากนั้น(อาจไม่จำเป็นต้องโทรreset()) ; แต่คุณถูกต้องในการชี้ฟังก์ชั่นนั้นซึ่งอาจมีประโยชน์
Pascal MARTIN

3
@PascalMARTIN +1 ฉันคิดว่าการเพิ่มความคิดเห็นเกี่ยวกับการรีเซ็ต () ในคำตอบของคุณจะมีประโยชน์มาก
Lulu

วิธีการนี้ใช้ไม่ได้หากอาร์เรย์มีค่าซ้ำกัน เช่น. เพราะarray('a', 'b', 'c', 'd', 'a')จะส่งคืนคีย์ 0 แทน 4
Marc

2
@ Marc วิธีการนี้ทำงานอย่างถูกต้องแม้ว่าจะมีค่าซ้ำกัน
Jeff

1
@pppp มันไม่ทำงานเพราะ ... ตรวจสอบสิ่งที่สิ้นสุด () ผลตอบแทนแล้วคิดอีกครั้ง;)
forsberg

79

แม้ว่าend()ดูเหมือนจะง่ายที่สุด แต่ก็ไม่เร็วที่สุด ทางเลือกที่เร็วกว่าและแข็งแกร่งกว่าคือarray_slice():

$lastKey = key(array_slice($array, -1, 1, true));

ดังที่การทดสอบบอกว่าในอาเรย์ที่มีองค์ประกอบ 500,000 มันก็เร็วขึ้นเกือบ 7 เท่า!


98
ตื่นเต้นกับคำตอบนี้ฉันทำแบบทดสอบ 100,000 ครั้งเปรียบเทียบ (a) end($arr);$key = key($arr);reset($arr);กับ (b) $key = key(array_slice($arr,-1,1,true));... ซึ่งทำให้end()เร็วขึ้นมาก! end () = 0.05326 วินาที, array_slice = 8.506 วินาที ... huh ??
neokio

54
ฟังก์ชั่นในตัวของ PHP นั้นถูกสร้างขึ้นโดยผู้สนใจมาก อย่าพยายามสร้างฟังก์ชั่นเหล่านั้นใหม่ โอกาสที่คุณทำบางสิ่งบางอย่างช้ากว่าต้นฉบับ เว้นแต่คุณจะเป็นพ่อมดที่ชั่วร้าย
dmmd

16
end()เร็วที่สุดเพราะสามารถหาได้จากฟังก์ชั่น C ที่ง่ายมากเช่น:int top(void){ int i; for(i = 0; stack[i] != '\0'; i++); return stack[--i]; }
Gustav

10
@Gustav ฉันเชื่อว่าการใช้ C-based พื้นฐานของ PHP มีตัวชี้ภายในlastเป็นองค์ประกอบสุดท้าย ทำให้end()O สวยมาก (1) :-)
Eric

15
@dmmd ฉันมั่นใจว่าทีม PHP จะต้องยินดีเป็นอย่างยิ่งที่เรียกว่า nerds
datasn.io

53

ฉันชอบ

end(array_keys($myarr))

19
ทำให้ STRICT NOTICE สิ้นสุดคาดว่าการอ้างอิงตัวแปร
Wiliam

25
คุณสามารถใช้end((array_keys($myarr)))เพื่อหลีกเลี่ยงการแจ้งให้ทราบล่วงหน้า
Ben Fortune

9
@BenFortune สิ่งนี้ได้รับการแก้ไขใน PHP7: "ใน PHP 5 การใช้วงเล็บที่ซ้ำซ้อนรอบพารามิเตอร์ฟังก์ชั่นอาจเงียบคำเตือนมาตรฐานที่เข้มงวดเมื่อพารามิเตอร์ของฟังก์ชั่นถูกส่งผ่านโดยอ้างอิงตอนนี้จะออกคำเตือนเสมอ"
Dominic Scheirlinck

นั่นเป็นคำเตือนที่ไม่จำเป็นทั้งหมด! มันเป็นเรื่องปกติและปกติในทุกภาษา!
azerafati

1
ในภาษาอื่น ๆ ฟังก์ชั่นไม่ทำงานบนพอยน์เตอร์ใช่ไหม?
jurchiks

52

ตั้งแต่PHP 7.3 (2018)มีฟังก์ชั่น (ในที่สุด) สำหรับสิ่งนี้: http://php.net/manual/en/function.array-key-last.php

$array = ['apple'=>10,'grape'=>15,'orange'=>20];
echo array_key_last ( $array )

จะส่งออก

orange

4
Horray! ฉันกำลังจะเพิ่มคำตอบนี้ คุณสามารถเน้นรุ่น "PHP 7.3" และปี 2018 ได้หรือไม่? มันจะง่ายกว่าที่จะเห็นข่าวที่น่ากลัวนี้ให้คนอื่น
Tomáš Votruba

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

30

เพียงใช้: echo $array[count($array) - 1];


75
ใช้งานได้เฉพาะถ้าคุณมีอาร์เรย์ที่เป็นตัวเลข ล้มเหลวด้วยอาร์เรย์ที่เชื่อมโยง
Jeremy J Starcher

12
สิ่งนี้ไม่เพียงทำงานในอาร์เรย์ที่เป็นตัวเลขเท่านั้น แต่ยังแสดงคีย์ไม่ได้ แต่แสดงค่าใช่หรือไม่
Nanne

ฉันเกินไปเจคที่เราสามารถทำสิ่งที่เราแยกนี้ (ช่วยให้มีความซื่อสัตย์) บน Google ตีทั้งตัวเลขและเชื่อมโยงเพื่อให้เรามีการอ้างอิงสําหรับทั้ง ... ผมทำงานเดียวที่ออกมามันเป็นรองหลังจากแยกint top(void){ int i; for(i = 0; stack[i] != '\0'; i++); return stack[--i]; }ซึ่งเป็น น่าสนใจ แต่ไม่ดีสำหรับธุรกิจเมื่อคุณมีเวลา จำกัด
lol

5
นอกจากนี้สำหรับอาร์เรย์ที่เป็นตัวเลขโปรดจำไว้ว่าอาร์เรย์ที่เป็นตัวเลขไม่จำเป็นต้องทำงานตามลำดับหรือใช้ตัวเลขทั้งหมด สิ่งนี้จะใช้งานได้หากคุณไม่ได้กำหนดค่าตัวเลขไว้อย่างชัดเจน แต่ถ้าคุณทำ$a[1] = 1; $a[5] = 5; $a[0] = 0;คุณจะมีอาเรย์ที่มีคีย์ (1, 5, 0) ตามลำดับ count($a)จะให้ผล 3 และ$a[2]ไม่ได้กำหนดไว้ มันไม่ได้ให้ 5 อย่างแน่นอน
Daniel Skarbek

1
อ่านคำถามอีกครั้ง "วิธีรับคีย์สุดท้ายในอาร์เรย์ได้อย่างไร"

20

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

มันแค่ต้องการตัวแปร ... ไม่ใช่เรื่องใหญ่ในการเขียนโค้ดอีกหนึ่งบรรทัดจากนั้นก็ยกเลิกมันถ้าคุณต้องการ

$array = array(
    'first' => 123,
    'second' => 456,
    'last' => 789, 
);

$keys = array_keys($array);
$last = end($keys);

2
คำตอบนี้ (ในขณะที่ถูกต้องทางเทคนิค) จะสิ้นเปลือง / ไม่มีประสิทธิภาพเพราะต้องสร้างอาร์เรย์เพิ่มเติม (ที่มีความยาวเท่ากับต้นฉบับ) ซึ่งหมายความว่าขยะจะเพิ่มขึ้นตามลำดับ สิ่งนี้ไม่ควรถูกเลือกเหนือคำตอบที่มีประสิทธิภาพของ Pascal MARTIN ฉันประหลาดใจที่นี่มี upvotes มากมาย
mickmackusa

12

ตั้งแต่PHP7.3คุณสามารถเข้าถึงคีย์สุดท้ายในโดยตรง (ระดับนอกของ) อาร์เรย์ที่มีarray_key_last ()

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

เกณฑ์มาตรฐานคร่าวๆเป็นหลักฐาน: https://3v4l.org/hO1Yf

array_slice() + key():  1.4
end() + key():         13.7
array_key_last():       0.00015

* อาร์เรย์ทดสอบมีองค์ประกอบ 500,000 รายการ microtime ทำซ้ำ 100x จากนั้นเฉลี่ยแล้วคูณด้วย 1,000 เพื่อหลีกเลี่ยงสัญลักษณ์ทางวิทยาศาสตร์ เครดิต @MAChitgarha สำหรับมาตรฐานเริ่มต้นแสดงความคิดเห็นภายใต้@ คำตอบของ

หมายความว่าคุณสามารถดึงค่าของคีย์สุดท้ายได้โดยไม่ต้อง:

  1. ย้ายตัวชี้อาร์เรย์ (ซึ่งต้องใช้รหัสสองบรรทัด) หรือ
  2. การเรียงลำดับการย้อนกลับการ popping การนับการจัดทำดัชนีอาร์เรย์ของคีย์หรือ tomfoolery อื่น ๆ

ฟังก์ชั่นนี้ค้างชำระเป็นเวลานานและนอกจากนี้ยังมีเข็มขัดเครื่องมือเสริมฟังก์ชั่นอาเรย์ที่ช่วยเพิ่มประสิทธิภาพหลีกเลี่ยงผลข้างเคียงที่ไม่พึงประสงค์

นี่คือตัวอย่าง :

$array = ["a" => "one", "b" => "two", "c" => "three"];
if (!function_exists('array_key_last')) {
    echo "please upgrade to php7.3";
} else {
    echo "First Key: " , key($array) , "\n";
    echo "Last Key: " , array_key_last($array) , "\n";
    next($array);                 // move array pointer to second element
    echo "Second Key: " , key($array) , "\n";
    echo "Still Last Key: " , array_key_last($array);
}

เอาท์พุท:

First Key: a
Last Key: c     // <-- unaffected by the pointer position, NICE!
Second Key: b
Last Key: c     // <-- unaffected by the pointer position, NICE!

หมายเหตุบางส่วน:

  • array_key_last() เป็นฟังก์ชั่นของพี่น้อง array_key_first ()
  • ทั้งสองฟังก์ชั่นเหล่านี้คือ "ตัวชี้ไม่รู้"
  • ฟังก์ชั่นทั้งสองกลับมา nullถ้าอาเรย์นั้นว่างเปล่า
  • ฟังก์ชันพี่น้องที่ถูกทิ้ง ( array_value_first()&array_value_last() ) ก็จะเสนอการเข้าถึงตัวชี้แบบไม่รู้เขินถึงองค์ประกอบ bookend แต่เห็นได้ชัดว่าพวกเขาล้มเหลวในการรวบรวมคะแนนเสียงที่เพียงพอที่จะมีชีวิตขึ้นมา

นี่คือหน้าที่เกี่ยวข้องบางส่วนที่พูดถึงคุณสมบัติใหม่:

ป.ล. หากใครกำลังชั่งน้ำหนักเทคนิคอื่น ๆ บางอย่างคุณอาจอ้างถึงชุดของการเปรียบเทียบขนาดเล็ก: ( สาธิต )

Duration of array_slice() + key():     0.35353660583496
Duration of end() + key():             6.7495584487915
Duration of array_key_last():          0.00025749206542969
Duration of array_keys() + end():      7.6123380661011
Duration of array_reverse() + key():   6.7875385284424
Duration of array_slice() + foreach(): 0.28870105743408

2
คำตอบนี้ควรอยู่ด้านบนของรายการ มันเสร็จสมบูรณ์แล้ว
จอห์น

1
ว้าว DV ในคำตอบของฉันนี้ อะไรคือสิ่งที่ครอบคลุมมากเกินไป / ชัดเจน / อธิบาย / สนับสนุน? pfft ดำเนินการต่อเพื่อผลักดันโพสต์ที่กล้าบอก ทำได้ดีมาก ในกรณีที่คุณไม่ทราบปุ่ม DV สำหรับโพสต์ที่ "ไม่มีประโยชน์" โปรดถามตัวเองว่าเป้าหมายของคุณคืออะไรที่นี่
mickmackusa

8

ลองใช้ฟังก์ชั่นarray_popและarray_keysดังนี้:

<?php

$array = array(
    'one' => 1,
    'two' => 2,
    'three' => 3
);

echo array_pop(array_keys($array)); // prints three

?>

14
มันช้ามากถ้าอาร์เรย์ของคุณมีมากกว่า 1 อย่าง โปรดอย่าทำเช่นนี้
Andrey

3
และทำให้เกิดการแจ้งเตือนอย่างเข้มงวดเช่นกันการอ้างอิงตัวแปร
Wiliam

array_pop () จะทำให้อาร์เรย์เดิมสั้นลง (ลบองค์ประกอบสุดท้าย) ฉันไม่แน่ใจว่าเรื่องนี้หรือไม่สำหรับ OP แต่จะมีความสำคัญต่อผู้อื่นอย่างแน่นอน
โปรแกรมเมอร์

1
ไม่ได้จริงๆ ในตัวอย่างนี้array_pop()ทำงานกับค่าตอบแทนของarray_keys()และไม่ได้อยู่ในอาร์เรย์เดิม
Petko Bossakov

เนื่องจากมีคำตอบอื่น ๆ ที่มีประสิทธิภาพมากกว่าที่ไม่ได้แจ้งให้ทราบล่วงหน้าฉันกำลัง downvoting คำตอบนี้
mickmackusa

6

ณ PHP> = 7.3 array_key_last()เป็นวิธีที่ดีที่สุดในการรับคีย์สุดท้ายของอาเรย์ใด ๆ โดยใช้การรวมend(), key()และreset()เพียงเพื่อให้ได้ที่สำคัญสุดท้ายของอาร์เรย์เป็นอุกอาจ

$array = array("one" => bird, "two" => "fish", 3 => "elephant");
$key = array_key_last($array);
var_dump($key) //output 3

เปรียบเทียบกับ

end($array)
$key = key($array)
var_dump($key) //output 3
reset($array)

คุณต้องรีเซ็ตอาร์เรย์เพื่อให้ตัวชี้อยู่ที่จุดเริ่มต้นหากคุณใช้การรวมกันของend()และkey()


4

ฉันต้องการเสนอทางเลือกอื่นในการแก้ไขปัญหานี้

สมมติว่าคีย์ทั้งหมดของคุณเป็นตัวเลขโดยไม่มีช่องว่างวิธีที่ฉันชอบคือการนับอาร์เรย์จากนั้นลบ 1 จากค่านั้น (เพื่อพิจารณาว่าคีย์อาร์เรย์เริ่มต้นที่ 0

$array = array(0=>'dog', 1=>'cat');

$lastKey = count($array)-1;
$lastKeyValue = $array[$lastKey];

var_dump($lastKey);
print_r($lastKeyValue);

สิ่งนี้จะทำให้คุณ:

แมว (1)


1
สิ่งนี้จะใช้งานไม่ได้กับอาเรย์ที่คีย์ไม่ได้เพิ่มขึ้นเช่นอาเรย์ (0 => 'dog', 5 => 'cat'); $ lastKey จะคืนค่าผิด
kakoma

@kakoma - ตามที่โพสต์ของฉันบอกว่า "สมมติว่าคีย์ทั้งหมดของคุณเป็นตัวเลขโดยไม่มีช่องว่าง"

สำหรับทุกคนที่มหัศจรรย์ใช้ "array_values" ของ PHP เพื่อ rekey อาร์เรย์เป็นลำดับตัวเลข php.net/manual/en/function.array-values.php

1
เนื่องจากคำตอบนี้เกี่ยวข้องกับเศษส่วนของความเป็นไปได้ของอาร์เรย์ (ตัวเลข, อาร์เรย์คีย์ที่ต่อเนื่องกัน) คำตอบนี้ไม่ได้เสนอคำตอบที่ถูกต้อง / ถูกต้องสำหรับคำถามทั่วไปของ OP downvote
mickmackusa

4

คุณสามารถใช้สิ่งนี้:

$array = array("one" => "apple", "two" => "orange", "three" => "pear");
end($array); 
echo key($array);

โซลูชันอื่นคือการสร้างฟังก์ชั่นและใช้งาน:

function endKey($array){
end($array);
return key($array);
}

$array = array("one" => "apple", "two" => "orange", "three" => "pear");
echo endKey($array);

1
คำตอบนี้ให้อะไรใหม่ที่ไม่ได้อยู่ในหัวข้อนี้
Martin

1
มาร์ตินไม่มีใครใช้ฟังก์ชั่นเพื่อให้ได้ผลลัพธ์
Atif Tariq

1
คุณต้องการเพิ่มโค้ด 1 บรรทัดในฟังก์ชันหรือไม่? นั่นเป็นอินเทอร์เฟซที่ค่อนข้างจำเป็น
มาร์ติน

1
มาร์ตินซึ่งหนึ่งบรรทัด
Atif Tariq

2
บรรทัดในการทำงานของคุณ
Martin

3
$arr = array('key1'=>'value1','key2'=>'value2','key3'=>'value3');
list($last_key) = each(array_reverse($arr));
print $last_key;
// key3

2
การย้อนกลับอาร์เรย์ทั้งหมดเพื่อดึงค่าเดียวนั้นมีประสิทธิภาพน้อยกว่าวิธีการของ PascalMARTIN อย่างแน่นอน แม้ว่าจะถูกต้องทางเทคนิค แต่ก็ไม่ควรใช้แทนวิธีการของ Pascal
mickmackusa

3

ฉันเพิ่งใช้ตัวช่วยจากแซนเดอร์และปรับปรุงด้วยคำตอบก่อนหน้านี้:

function last($array){
  $keys = array_keys($array);
  return end($keys);
}


$arr = array("one" => "apple", "two" => "orange", "three" => "pear");    
echo last($arr);
echo $arr(last($arr));



0
$array = array(
    'something' => array(1,2,3),
    'somethingelse' => array(1,2,3,4)
);

$last_value = end($array);
$last_key = key($array); // 'somethingelse'

ใช้งานได้เนื่องจาก PHP ย้ายตัวชี้อาร์เรย์ไปภายในเพื่อ $ array


2
นี่เป็นวิธีการซ้ำของ PascalMARTIN โปรดสำรองหน้านี้และลบคำตอบสาย / ซ้ำของคุณ downvoted
mickmackusa

0

ทางออกที่ดีที่สุดที่สามารถใช้อินไลน์ได้:

end($arr) && false ?: key($arr)

โซลูชันนี้เป็นเพียงนิพจน์ / คำสั่งและการให้ดีไม่ใช่ประสิทธิภาพที่ดีที่สุด

การใช้ตัวอย่างแบบอินไลน์:

$obj->setValue(
    end($arr) && false ?: key($arr) // last $arr key
);


อัพเดท: ใน PHP 7.3+: ใช้ (แน่นอน) array_key_last()วิธีการที่เพิ่งเพิ่มเข้ามา

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