Bir dizideki son anahtarı nasıl alabilirim?


335

Bir dizinin son anahtarını nasıl alabilirim?


10
İlişkilendirilebilir dizi, sayısal dizi veya her ikisinde de çalışması gerekiyorsa belirtmelidir.
Jimbo Jonny

sık sorulan soru
Josua Marcel Chrisano

Yanıtlar:


610

Bir çözüm endve (alıntı) kombinasyonu kullanmak olacaktır :key

  • end() dizinin iç işaretçisini son öğeye ilerletir ve değerini döndürür.
  • key() geçerli dizi konumunun dizin öğesini döndürür.

Yani, bunun gibi bir kod hile yapmalıdır:

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

Çıktı olacak:

string 'last' (length=4)

yani dizimin son elemanının anahtarı.

Bu yapıldıktan sonra dizinin dahili işaretçisi dizinin sonunda olacaktır. Yorumlarda belirtildiği gibi reset(), işaretçiyi dizinin başına getirmek için dizide çalıştırmak isteyebilirsiniz .


17
@Pim: OP'nin bu diziden sonra ne yapmak istediğine bağlıdır (çağırmak gerekmeyebilir reset()) ;; ama yararlı olabilecek bu işlevi göstermekte haklısınız.
Pascal MARTIN

3
@PascalMARTIN +1 Bence cevabınıza reset () hakkında yorum eklemek çok yardımcı olacaktır.
Lulu

Dizide yinelenen değerler varsa bu yaklaşım çalışmaz. Örneğin. çünkü array('a', 'b', 'c', 'd', 'a')4 yerine 0 anahtarını döndürür.
Marc

2
@Marc yinelenen değer olsa bile bu yaklaşım düzgün çalışır.
Jeff

1
@pppp işe yaramaz çünkü ... hangi sonun () geri döndüğünü kontrol edip tekrar düşünün;)
forsberg

79

Her ne kadar end()kolay gibi görünüyor, bu hızlı değil. Daha hızlı ve daha güçlü alternatif array_slice():

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

Testlerin söylediği gibi , 500000 elemanlı bir dizide neredeyse 7 kat daha hızlı!


98
Bu cevapla heyecanlı, 100.000 iterasyonun hızlı bir testini yaptım, (a) ' end($arr);$key = key($arr);reset($arr);yı (b) ile karşılaştırarak $key = key(array_slice($arr,-1,1,true));... end()ÇOK daha hızlı olmasına neden oldu ! end () = 0.05326 saniye, array_slice = 8.506 saniye ... ha ??
neokio

54
PHP'nin yerleşik işlevleri aşırı inekler tarafından inşa edildi. Bu işlevleri yeniden oluşturmaya çalışmayın. Muhtemelen orijinalinden çok daha yavaş bir şey yapmanızdır. Bir tür kötü büyücü olmadıkça, çünkü.
dmmd

16
end()en hızlı çünkü çok basit bir C fonksiyonundan türetilebilir, örneğin:int top(void){ int i; for(i = 0; stack[i] != '\0'; i++); return stack[--i]; }
Gustav

10
@Gustav PHP'nin altında yatan C-uygulamasının, aslında lastson öğeye dahili bir işaretçisi olduğuna inanıyorum . Hemen end()hemen O (1) yapmak. :-)
Eric

15
@ dmmd, eminim PHP ekibi nerds denir aşırı memnun olurdu.
datasn.io

53

tercih ederim

end(array_keys($myarr))

19
STRICT BİLDİRİMİNE neden olur, sonunda değişken bir referans
beklenir

25
end((array_keys($myarr)))Bildirimde gezinmek için kullanabilirsiniz .
Ben Fortune

9
@BenFortune Bu PHP7'de düzeltildi: "PHP 5'te, bir işlev parametresinin etrafında yedek parantez kullanılması, işlev parametresi başvuru ile geçtiğinde katı standart uyarılarını susturabilir. Şimdi uyarı her zaman verilecektir."
Dominic Scheirlinck

bu tamamen gereksiz bir uyarı! diğer tüm dillerde normal ve olağan şeyler!
azerafati

1
Diğer dillerde, işlevler işaretçiler üzerinde çalışmaz, değil mi?
jurchiks

52

PHP 7.3 (2018) 'den beri bunun için (nihayet) bir işlev vardır: http://php.net/manual/en/function.array-key-last.php

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

çıktı olacak

orange

4
Horray! Bu cevabı eklemek üzereydim. "PHP 7.3" sürümünü ve 2018 yılını vurgulayabilir misiniz? Bu harika haberi başkaları için fark etmek daha kolay olacak
Tomáš Votruba

Ayrıca bunun dahili dizi işaretçisini ETKİLEMEDİĞİNİ de belirtmek gerekir.
mvorisek

30

Sadece kullan : echo $array[count($array) - 1];


75
Bu yalnızca sayısal dizileriniz varsa işe yarar. İlişkilendirilmiş dizilerle başarısız olur.
Jeremy J Starcher

12
Bu sadece sayısal dizilerde işe yaramaz, aynı zamanda anahtarı gösteremez, değeri gösterir, değil mi?
Nanne

Ben de jake, biz bu (dürüst olalım) üst google hit hem sayısal hem de ilişkisel içine bölünmüş bir şey yapabilir miyiz, böylece her ikisi için eski bir referans var ... Ben sadece ayrıştıktan sonra assoc için int top(void){ int i; for(i = 0; stack[i] != '\0'; i++); return stack[--i]; }hangi olduğunu öğrendim zaman bütçesinde olduğunuzda ilginç ama iş için iyi değil
lol

5
Ayrıca, sayısal bir dizi için bile, sayısal dizilerin sırayla gitmesi veya tüm sayıları kullanması gerekmediğini unutmayın. Bu, açıkça sayısal değerlere atamazsanız çalışır, ancak bunu yaparsanız $a[1] = 1; $a[5] = 5; $a[0] = 0;, o sırayla (1, 5, 0) tuşlarına sahip bir diziniz olacaktır. count($a)3 verir ve $a[2]tanımlanmaz. Kesinlikle size 5 geri vermiyor.
Daniel Skarbek

1
" Bir dizideki son anahtar nasıl alınır ?"

20

Bunun daha hızlı olup olmayacağını bilmiyorum, ama bu şekilde yapmak daha kolay görünüyor ve bitirmek için bir işlevden geçerek () ...

sadece bir değişkene ihtiyacı vardı ... bir kod satırı daha yazmak için büyük bir anlaşma değil, sonra gerekiyorsa ayarını kaldırın.

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

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

2
Bu cevap (teknik olarak doğru olsa da) israf / verimsizdir çünkü ek bir dizi (orijinal ile eşit uzunlukta) oluşturulmasını gerektirir. Bu, orijinal dizi büyüdükçe atığın arttığı anlamına gelir. Bu asla Pascal MARTIN'in etkili cevabı üzerinden seçilmemelidir. Bu kadar çok upvotes olduğunu şaşırdım.
mickmackusa

12

PHP7.3'ten itibaren array_key_last () ile bir dizideki (dış seviye) son anahtara doğrudan erişebilirsiniz.

Kesinlikle bu sayfadaki tartışmanın çoğunu yatağa koyar. En iyi performansı gösteren, hiçbir yan etkisi olmayan ve bu sorunun tam olarak aradığı şeyi iletmek için doğrudan, sezgisel, tek çağrı tekniğidir.

Kanıt olarak kabaca bir kıyaslama: https://3v4l.org/hO1Yf

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

* Test dizisi 500000 element içerir, mikrotime 100x tekrarlanır, ardından ortalaması alınır ve bilimsel gösterimi önlemek için 1000 ile çarpılır. İlk test için @Mhithitgarha'ya @ TadejMagajna'nın cevabı altında yorum yaptı .

Bu, son anahtarın değerini aşağıdakiler olmadan alabileceğiniz anlamına gelir:

  1. dizi işaretçisini taşımak (iki kod satırı gerektirir) veya
  2. bir anahtar dizisini veya diğer herhangi bir tomrukçuluku sıralamak, tersine çevirmek, patlatmak, saymak, dizine eklemek

Bu işlev gecikmişti ve dizi işlev aracı kayışına performansı artıran, istenmeyen yan etkileri önleyen ve temiz / doğrudan / sezgisel kod sağlayan hoş bir eklentiydi.

İşte bir 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);
}

Çıktı:

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

Bazı notlar:

  • array_key_last()array_key_first () öğesinin kardeş işlevidir .
  • Bu işlevlerin her ikisi de "pointer-cahil" dir.
  • Her iki işlev de geri döner nullDizi boşsa .
  • Atılan kardeş işlevleri ( array_value_first()& array_value_last()) de, kitap ucu öğelerine işaretçi-cahil erişim sunacaktı, ancak açık bir şekilde hayata geçmek için yeterli oy toplayamadılar.

İşte yeni özellikleri tartışan alakalı sayfalar:

ps Eğer birisi diğer tekniklerden bazılarını tartıyorsa, bu küçük karşılaştırma koleksiyonuna başvurabilirsiniz: ( Demo )

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
Bu cevap listenin başında olmalıdır. Sadece tamamlandı.
John

1
Vay, BU cevabım üzerine bir DV? Çok kapsamlı / kesin / açıklayıcı / desteklenen mesele neydi? Pfft. Kesinlikle bilgilendirmeye cesaret eden mesajları aşağı itmeye devam edin. Aferin. Bilmiyorsanız, DV düğmesi "yararlı olmayan" gönderiler içindir. Lütfen kendinize burada hedefinizin ne olduğunu sorun.
mickmackusa

8

Array_pop ve array_keys işlevini aşağıdaki gibi kullanmayı deneyin :

<?php

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

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

?>

14
Dizinizde 1'den fazla şey varsa bu gerçekten yavaştır. Lütfen bunu yapma.
Andrey

3
ve değişken referans, çok KESİN BİLDİRİM neden olur
Wiliam

array_pop (), orijinal diziyi kısaltır (son öğeyi kaldırarak). Bunun OP için önemli olup olmadığından emin değilim ama kesinlikle başkaları için önemli olacak.
Programcı

1
Pek sayılmaz. Bu örnekte, array_pop()dönüş değeri ile çalışır array_keys()ve olmayan orijinal dizi.
Petko Bossakov

Bir BİLDİRİM'i tetiklemeyen daha verimli cevaplar olduğu için bu cevabı küçümsüyorum.
mickmackusa

6

PHP'den itibaren> = 7.3 array_key_last(), bir dizinin son anahtarını almanın en iyi yoludur. Bir dizinin son anahtarını almak için end(), key()ve reset()sadece kombinasyonunu kullanmak çirkin.

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

ile karşılaştır

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

end()Ve kombinasyonlarını kullanıyorsanız işaretçinin başında olması için diziyi sıfırlamanız gerekir.key()


4

Ayrıca bu soruna alternatif bir çözüm sunmak istiyorum.

Tüm anahtarlarınızın boşluk olmadan sayısal olduğu varsayılırsa, tercih ettiğim yöntem diziyi daha sonra bu değerden eksi 1 saymaktır (dizi anahtarlarının 0'dan başlaması gerçeğini hesaba katmak).

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

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

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

Bu size:

int (1) kedi


1
Bu, anahtarların artımlı olmadığı diziler için çalışmaz, örneğin dizi (0 => 'köpek', 5 => 'kedi'); $ lastKey yanlış bir değer döndürür
kakoma

@kakoma - Yazımda "Tüm anahtarlarınızın boşluk olmadan sayısal olduğu varsayılarak" söylendiği gibi.

Mucizeler için diziyi sayısal sıraya sokmak için PHP'nin "dizi_değerleri" ni kullanın. php.net/manual/tr/function.array-values.php

1
Bu cevap sadece dizi olasılıklarının bir kısmını ele aldığından (sayısal, ardışık anahtar dizileri), bu cevap OP'nin genel sorusuna sağlam / doğru bir cevap sunmaz. Downvote.
mickmackusa

4

Bunu kullanabilirsiniz:

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

Başka bir Çözüm, bir işlev oluşturmak ve kullanmaktır:

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

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

1
Bu yanıt, bu konuda henüz yer almayan yeni bir şey sağlamıyor.
Martin

1
Martin, hiç kimse sonucu elde etmek için işlevi kullanmaz.
Atif Tarık

1
bir işleve 1 satır kod eklemeniz gerekiyor mu? Bu oldukça gereksiz bir arayüz.
Martin

1
Martin, bir satır.
Atif Tarık

2
fonksiyonunuzdaki çizgi
Martin

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

2
Tüm diziyi yalnızca bir değer çekmek için tersine çevirmek kesinlikle PascalMARTIN'in yönteminden daha az verimlidir. Teknik olarak doğru olmasına rağmen asla Pascal'ın yaklaşımı yerine kullanılmamalıdır.
mickmackusa

3

Xander'dan yardımcı işlevi aldım ve daha önce verilen cevaplarla geliştirdim:

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

Bunu ile deneyin array_reverse().

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

1

Garip, ama bu konunun neden bu cevabı yok:

$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'

PHP, dizi işaretçisini $ dizi için dahili olarak taşıdığı için çalışır


2
Bu, PascalMARTIN'in yönteminin bir kopyasıdır. Lütfen bu sayfayı yedekleyin ve geç / yinelenen cevabınızı silin. Downvoted.
mickmackusa

0

Satır içi de kullanılabilecek mümkün olan en iyi çözüm:

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

Bu çözüm yalnızca ifade / deyimdir ve iyi olanın mümkün olan en iyi performans olmadığını gösterir.

Çizgisel örnek kullanımı:

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


GÜNCELLEME: PHP 7.3 ve sonraki sürümlerinde: (tabii ki) yeni eklenen array_key_last()yöntemi kullanın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.