Làm thế nào để có được khóa cuối cùng trong một mảng?


335

Làm thế nào tôi có thể nhận được khóa cuối cùng của một mảng?


10
Nên chỉ định mảng kết hợp, mảng số hoặc nếu phải làm việc trên cả hai.
Jimbo Jonny

câu hỏi thường gặp
Josua Marcel Chrisano

Câu trả lời:


610

Một giải pháp sẽ là sử dụng kết hợp end(trích dẫn) :key

  • end() tiến con trỏ bên trong của mảng đến phần tử cuối cùng và trả về giá trị của nó.
  • key() trả về phần tử chỉ mục của vị trí mảng hiện tại.

Vì vậy, một phần của mã như thế này nên thực hiện thủ thuật:

$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);

Sẽ xuất:

string 'last' (length=4)

tức là khóa của phần tử cuối cùng của mảng của tôi.

Sau khi hoàn thành, con trỏ bên trong của mảng sẽ ở cuối mảng. Như đã chỉ ra trong các ý kiến, bạn có thể muốn chạy reset()trên mảng để đưa con trỏ trở lại đầu mảng.


17
@Pim: phụ thuộc vào những gì OP muốn làm với mảng đó sau (có thể không cần gọi reset()) ;; nhưng bạn đã đúng khi chỉ ra chức năng đó, có thể hữu ích.
Pascal MARTIN

3
@PascalMARTIN +1 Tôi nghĩ rằng việc thêm nhận xét về thiết lập lại () trong câu trả lời của bạn sẽ rất hữu ích.
Lulu

Cách tiếp cận này không hoạt động nếu mảng có các giá trị trùng lặp. ví dụ. vì array('a', 'b', 'c', 'd', 'a')nó sẽ trả về khóa 0 thay vì 4.
Marc

2
@Marc phương pháp này hoạt động chính xác ngay cả khi có giá trị trùng lặp.
Jeff

1
@pppp nó không hoạt động vì ... kiểm tra xem end () trả về và sau đó suy nghĩ lại;)
forsberg

79

Mặc dù end()có vẻ là dễ nhất, nhưng nó không phải là nhanh nhất. Sự thay thế nhanh hơn và mạnh hơn nhiều là array_slice():

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

Như các thử nghiệm nói , trên một mảng có 500000 phần tử, nó nhanh hơn gần 7 lần!


98
hào hứng với câu trả lời này, tôi đã làm một bài kiểm tra nhanh gồm 100.000 lần lặp, so sánh (a) end($arr);$key = key($arr);reset($arr);với (b) $key = key(array_slice($arr,-1,1,true));... kết quả end()là NHIỀU nhanh hơn! end () = 0,05326 giây, mảng_slice = 8,506 giây ... hả ??
neokio

54
Các hàm dựng sẵn của PHP được xây dựng bởi các mọt sách cực đoan. Đừng cố gắng tạo lại các chức năng đó. Tỷ lệ cược là bạn làm cho một cái gì đó chậm hơn so với ban đầu. Trừ khi bạn là một loại phù thủy độc ác, của couse.
dmmd 18/03/13

16
end()là nhanh nhất vì nó có thể được bắt nguồn từ một hàm C rất đơn giản, chẳng hạn như:int top(void){ int i; for(i = 0; stack[i] != '\0'; i++); return stack[--i]; }
Gustav

10
@Gustav Tôi tin rằng việc triển khai C cơ bản của PHP, thực sự có một con trỏ bên trong lastđến phần tử cuối cùng. Làm end()khá nhiều O (1). :-)
Eric

15
@dmmd, tôi chắc chắn rằng nhóm PHP sẽ rất hài lòng vì họ được gọi là mọt sách.
datan.io

53

tôi thích

end(array_keys($myarr))

19
gây ra THÔNG BÁO CHIẾN LƯỢC, kết thúc mong đợi một tham chiếu thay đổi
Wiliam

25
Bạn có thể sử dụng end((array_keys($myarr)))để có được xung quanh thông báo.
Ben Fortune

9
@BenFortune Điều này đã được sửa trong PHP7: "Trong PHP 5, sử dụng dấu ngoặc đơn thừa xung quanh một tham số hàm có thể làm giảm các cảnh báo tiêu chuẩn nghiêm ngặt khi tham số hàm được truyền bằng tham chiếu. Cảnh báo sẽ luôn được đưa ra."
Đaminh Scheirlinck

Đó là một cảnh báo hoàn toàn không cần thiết! đó là một thứ bình thường và bình thường trong tất cả các ngôn ngữ khác!
azerafati 6/2/2016

1
Trong các ngôn ngữ khác, các chức năng không hoạt động trên con trỏ, phải không?
jicksiks

52

PHP 7.3 (2018) có chức năng (cuối cùng) cho việc này: http://php.net/manual/en/feft.array-key-last.php

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

sẽ xuất

orange

4
Kinh hoàng! Tôi đã định thêm câu trả lời này. Bạn có thể làm nổi bật phiên bản "PHP 7.3" và năm 2018 không? Sẽ dễ dàng hơn để phát hiện tin tức tuyệt vời này cho những người khác
Tomáš Votruba

Cũng tốt để đề cập rằng điều này KHÔNG ảnh hưởng đến con trỏ mảng bên trong.
mvorisek

30

Chỉ dùng : echo $array[count($array) - 1];


75
Điều này chỉ hoạt động nếu bạn có mảng số. Thất bại với mảng liên kết.
Jeremy J Starcher

12
Điều này không chỉ hoạt động trên các mảng số, nó không hiển thị khóa mà còn hiển thị giá trị, phải không?
Nanne

me too jake, chúng ta có thể làm một điều mà chúng tôi chia này (cho phép một cách trung thực) trên google hit vào cả hai số và kết hợp để chúng ta có một tham chiếu cũ cho cả ... Tôi chỉ làm việc ra đó là vì assoc sau khi phân tích int top(void){ int i; for(i = 0; stack[i] != '\0'; i++); return stack[--i]; }đó là thú vị nhưng không tốt cho kinh doanh khi bạn có ngân sách thời gian
lol

5
Ngoài ra, ngay cả đối với một mảng số, hãy nhớ rằng các mảng số không phải đi theo thứ tự hoặc sử dụng tất cả các số. Điều này sẽ hoạt động nếu bạn không gán rõ ràng cho các giá trị số, nhưng nếu bạn thực hiện $a[1] = 1; $a[5] = 5; $a[0] = 0;thì bạn sẽ có một mảng với các khóa (1, 5, 0), theo thứ tự đó. count($a)sẽ mang lại 3 và $a[2]không được xác định. Nó chắc chắn không cung cấp cho bạn 5 trở lại.
Daniel Skarbek

1
Đọc lại câu hỏi "Làm thế nào để lấy khóa cuối cùng trong một mảng?"

20

Không biết điều này sẽ nhanh hơn hay không, nhưng có vẻ dễ dàng hơn để làm theo cách này và bạn tránh được lỗi bằng cách không chuyển vào một hàm để kết thúc () ...

nó chỉ cần một biến ... không phải là vấn đề lớn để viết thêm một dòng mã, sau đó bỏ đặt nó nếu bạn cần.

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

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

2
Câu trả lời này (trong khi đúng về mặt kỹ thuật) là lãng phí / không hiệu quả vì nó yêu cầu tạo ra một mảng bổ sung (có độ dài bằng với bản gốc). Điều này có nghĩa là chất thải tăng như mảng ban đầu. Điều này không bao giờ nên được chọn qua câu trả lời hiệu quả của Pascal MARTIN. Tôi ngạc nhiên điều này có rất nhiều upvote.
mickmackusa

12

Kể từ PHP7.3, bạn có thể truy cập trực tiếp vào khóa cuối cùng trong (cấp độ bên ngoài) của một mảng với mảng_key_last ()

Việc dứt khoát đặt nhiều cuộc tranh luận trên trang này lên giường. Đây là người thực hiện tốt nhất, không có tác dụng phụ và là một kỹ thuật gọi trực tiếp, trực quan, để cung cấp chính xác những gì câu hỏi này tìm kiếm.

Một điểm chuẩn thô như bằng chứng: https://3v4l.org/hO1Yf

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

* mảng thử nghiệm chứa 500000 phần tử, microtime lặp lại 100 lần sau đó tính trung bình sau đó nhân với 1000 để tránh ký hiệu khoa học. Tín dụng cho @MAChitgarha cho điểm chuẩn ban đầu được nhận xét dưới câu trả lời của @ TadejMagajna .

Điều này có nghĩa là bạn có thể truy xuất giá trị của khóa cuối cùng mà không cần:

  1. di chuyển con trỏ mảng (yêu cầu hai dòng mã) hoặc
  2. sắp xếp, đảo ngược, xuất hiện, đếm, lập chỉ mục một mảng các khóa hoặc bất kỳ tính năng tomfoolery nào khác

Chức năng này đã quá hạn lâu và là sự bổ sung đáng hoan nghênh cho vành đai công cụ chức năng mảng giúp cải thiện hiệu suất, tránh các tác dụng phụ không mong muốn và cho phép mã sạch / trực tiếp / trực quan.

Đây là một bản demo :

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

Đầu ra:

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

Một số lưu ý:

  • array_key_last()là hàm anh chị em của mảng_key_first () .
  • Cả hai chức năng này là "không biết gì về con trỏ".
  • Cả hai hàm trả về nullnếu mảng trống.
  • Các chức năng anh chị em bị loại bỏ ( array_value_first()& array_value_last()) cũng sẽ cung cấp quyền truy cập không biết đến con trỏ vào các yếu tố boopool, nhưng rõ ràng là chúng đã thất bại trong việc thu thập đủ phiếu bầu để đi vào cuộc sống.

Dưới đây là một số trang có liên quan thảo luận về các tính năng mới:

ps Nếu bất cứ ai đang cân nhắc một số kỹ thuật khác, bạn có thể tham khảo bộ sưu tập so sánh nhỏ này: ( Bản trình diễn )

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
Câu trả lời này nên được đứng đầu danh sách. Nó chỉ đơn giản là hoàn thành.
John

1
Wow, một DV về câu trả lời NÀY của tôi? Vấn đề là gì, quá toàn diện / dứt khoát / giải thích / hỗ trợ? Pfft. Chắc chắn tiếp tục đẩy bài viết xuống mà dám thông báo. Làm tốt lắm. Trong trường hợp bạn không biết, nút DV dành cho các bài đăng "không hữu ích". Hãy tự hỏi mục tiêu của bạn là gì ở đây.
mickmackusa

8

Hãy thử sử dụng array_poparray_keys chức năng như sau:

<?php

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

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

?>

14
Điều này thực sự chậm nếu mảng của bạn có nhiều hơn 1 thứ trong đó. Xin đừng làm điều này.
Andrey

3
và cũng gây ra THÔNG BÁO CHIẾN LƯỢC, tham chiếu biến
Wiliam

mảng_pop () sẽ rút ngắn mảng ban đầu (loại bỏ phần tử cuối cùng). Tôi không chắc điều này có quan trọng hay không đối với OP nhưng chắc chắn sẽ quan trọng với người khác.
trình viên

1
Không hẳn vậy. Trong ví dụ này array_pop()hoạt động dựa trên giá trị trả về array_keys()không phải trên mảng ban đầu.
Petko Bossakov

Bởi vì có những câu trả lời hiệu quả khác không kích hoạt THÔNG BÁO, tôi sẽ hạ thấp câu trả lời này.
mickmackusa

6

Kể từ PHP> = 7.3 array_key_last()là cách tốt nhất để lấy khóa cuối cùng của bất kỳ mảng nào. Sử dụng kết hợp end(), key()reset()chỉ để có được chìa khóa cuối cùng của một mảng là thái quá.

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

so sánh nó với

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

Bạn phải đặt lại mảng cho con trỏ ở đầu nếu bạn đang sử dụng kết hợp end()key()


4

Tôi cũng muốn cung cấp một giải pháp thay thế cho vấn đề này.

Giả sử tất cả các khóa của bạn là số mà không có bất kỳ khoảng trống nào, phương pháp ưa thích của tôi là đếm mảng sau đó trừ 1 từ giá trị đó (để tính đến thực tế là các khóa mảng bắt đầu từ 0.

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

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

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

Điều này sẽ cung cấp cho bạn:

int (1) mèo


1
Điều này sẽ không hoạt động đối với mảng trong đó các khóa không tăng dần, ví dụ như mảng (0 => 'dog', 5 => 'cat'); $ lastKey sẽ trả về một giá trị sai
kakoma

@kakoma - Như bài đăng của tôi nói "Giả sử tất cả các khóa của bạn là số mà không có bất kỳ khoảng trống nào".

Đối với bất kỳ ai thắc mắc sử dụng "Array_values" của PHP để gắn lại mảng thành chuỗi số. php.net/manual/en/function.array-values.php

1
Vì câu trả lời này chỉ liên quan đến một phần nhỏ các khả năng của mảng (mảng số, khóa liên tiếp), nên câu trả lời này không đưa ra câu trả lời mạnh mẽ / chính xác cho câu hỏi chung chung của OP. Downvote.
mickmackusa

4

Bạn có thể sử dụng điều này:

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

Một giải pháp khác là tạo một hàm và sử dụng nó:

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

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

1
Câu trả lời này cung cấp không có gì mới mà chưa có trong chủ đề này.
Martin

1
Martin, không ai sử dụng chức năng để có được kết quả.
Atif Tariq

1
Bạn có cần thêm 1 dòng mã vào một hàm không? Đó là một giao diện khá không cần thiết.
Martin

1
Martin, một dòng.
Atif Tariq

2
dòng trong chức năng của bạn
Martin

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

2
Việc đảo ngược toàn bộ mảng chỉ để kéo một giá trị chắc chắn kém hiệu quả hơn phương thức của PascalMARTIN. Mặc dù nó đúng về mặt kỹ thuật, nó không bao giờ nên được sử dụng thay cho cách tiếp cận của Pascal.
mickmackusa

3

Tôi vừa lấy hàm trợ giúp từ Xander và cải thiện nó bằng các câu trả lời trước:

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));

1

Hãy thử cái này với array_reverse().

 $arr = array(
     'first' => 01,
     'second' => 10,
     'third' => 20, 
 );  
 $key = key(array_reverse($arr));
 var_dump($key);

1

Thật lạ, nhưng tại sao chủ đề này không có câu trả lời này:

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


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

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

Điều này hoạt động vì PHP di chuyển con trỏ mảng bên trong cho $ mảng


2
Đây là bản sao của phương thức PascalMARTIN. Vui lòng phụ tùng trang này và xóa câu trả lời trễ / trùng lặp của bạn. Bị hạ bệ.
mickmackusa

0

Giải pháp tốt nhất có thể được sử dụng nội tuyến được sử dụng:

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

Giải pháp này chỉ là biểu thức / tuyên bố và cung cấp tốt không phải là hiệu suất tốt nhất có thể.

Sử dụng ví dụ nội tuyến:

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


CẬP NHẬT: Trong PHP 7.3+: sử dụng (tất nhiên) array_key_last()phương thức mới được thêm vào .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.