Bir dizinin son öğesini silmeden almanın en iyi yolu nedir?


427

Tamam,

Her şeyi biliyorum array_pop(), ama bu son elementi siler. Bir dizinin son öğesini silmeden almanın en iyi yolu nedir?

EDIT: İşte bir bonus:

$array = array('a' => 'a', 'b' => 'b', 'c' => 'c');

ya da

$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
İster inanın ister inanmayın ve tekrar takmak bunu yaparken kıyasladığım en hızlı yollardan biri. $ val = $ dizi [] = array_pop ($ dizi); echo $ val;
user2782001

2
Bu soru birçok seçeneğe yol açtı. Seçmeme yardımcı olmak için, en dikkate değer / farklı seçeneklerin bazılarını karşılaştırdım ve sonuçları ayrı bir cevap olarak paylaştım . (: @ user2782001 yukarıdaki yorumda şimdiye kadar favorimi önerdi. :) Katkıda bulunduğunuz için herkese teşekkürler!
Paul van Leeuwen

1
@TheodoreRSmith PHP 7.3 yayınlandığında ( Quasimodo'nun klonu tarafından bu öneri 'kabul edilen cevap' (sizin değerlendirmeniz için) yapmayı düşünebilirsiniz ...
Paul van Leeuwen

Yanıtlar:


175

Bu konudaki birçok cevap bize birçok farklı seçenek sunuyor. Onlardan seçim yapabilmek için davranışlarını ve performanslarını anlamam gerekiyordu. Bu cevap olarak PHP sürümleri karşılaştırmanız seninle bulgularımı paylaşacak 5.6.38, 7.2.10ve 7.3.0RC1( 2018 13 Aralık beklenen ).

<<option code>>Test edeceğim seçenekler :

(fonksiyonlar söz: array_key_last , array_keys , array_pop , array_slice , array_values , sayım , son , sıfırlama )

Şunlarla <<input code>>birleştirilecek test girişleri :

  • null =$array = null;
  • boş =$array = [];
  • last_null =$array = ["a","b","c",null];
  • auto_idx =$array = ["a","b","c","d"];
  • karıştır =$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; }

Test için 5.6.38, 7.2.10ve 7.3.0RC1 PHP docker kapsayıcılar kullanacağım :

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

Yukarıda listelenen her <<option code>>s ve <<input code>>s kombinasyonu , PHP'nin tüm sürümlerinde çalıştırılır. Her test çalıştırması için aşağıdaki kod snippet'i kullanılır:

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

Her çalışma için bu, test girişinin son alınan son değerini değiştirir ve femtosaniye cinsinden bir yinelemenin ortalama süresini yazdırır (saniyenin 0,000000000000001th).

Sonuçlar aşağıdaki gibidir:

/==========================================================================================================================================================================================================================================================================================================================================================================================================================\
||                                                                      ||                            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 ||
 \=========================================================================================================================================================================================================================================================================================================================================================================================================================/ 

Yukarıda belirtilen F Atal, B UYARI ve N kodları olarak tercüme 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

Bu çıktıya dayanarak aşağıdaki sonuçları çıkarıyorum:

  • PHP'nin daha yeni sürümleri, önemli ölçüde yavaşlayan bu seçenekler dışında daha iyi performans gösterir:
    • seçenek .6. $x = end((array_values($array)));
    • seçenek .8. $keys = array_keys($array); $x = $array[$keys[count($keys)-1]];
  • bu seçenekler çok büyük diziler için en iyi ölçeği oluşturur:
    • seçenek .5. $x = end($array); reset($array);
    • seçenek .7. $x = $array[count($array)-1];
    • seçenek .9. $x = $array[] = array_pop($array);
    • seçenek 10. $x = $array[array_key_last($array)]; (PHP 7.3'ten beri)
  • bu seçenekler yalnızca otomatik dizinli diziler için kullanılmalıdır :
    • seçenek .7. $x = $array[count($array)-1];(kullanımı nedeniylecount)
    • seçenek .9. $x = $array[] = array_pop($array);(değer kaybeden orijinal anahtarın atanması nedeniyle)
  • bu seçenek dizinin dahili işaretçisini korumaz
    • seçenek .5. $x = end($array); reset($array);
  • bu seçenek, seçenek .5'i değiştirme girişimidir . dizinin dahili işaretçisini korumak için (ama ne yazık ki çok büyük diziler için iyi ölçeklenmiyor)
    • seçenek .6. $x = end((array_values($array)));
  • yeni array_key_lastişlevin, bu yazma sırasında hala bir RC olması dışında, yukarıda belirtilen sınırlamalardan hiçbirine sahip olmadığı görülüyor (bu nedenle RC'yi kullanın veya Aralık 2018'de yayınlanmasını bekleyin):
    • seçenek 10. $x = $array[array_key_last($array)]; (PHP 7.3'ten beri)

Diziyi yığın olarak mı yoksa kuyruk olarakkullandığınıza bağlı olarak , seçenek 9'da varyasyon yapabilirsiniz.


Eksik olmak için belirli bir seçenek bulursanız, yukarıdaki kod snippet'lerini kopyalayıp, daha önce test edilmiş bir seçenekle karşılaştırarak kendiniz test edebilirsiniz. Bu listeye bir seçenek eklemek, karşılaştırılabilir performans sonuçları için tüm kombinasyonları yeniden test etmek olacaktır. Eklenmesi gerektiğini düşündüğünüz belirli bir seçeneğiniz varsa, lütfen bir yorum bırakın, daha sonra eklemeyi düşünüyorum (biraz zaman alabilir).
Paul van Leeuwen

1
Çok büyük bir cevap, ancak bir yorum: ilişkilendirilebilir diziler için seçenek 9 da kullanılamaz, çünkü önceki anahtar adı yerine otomatik dizinli bir anahtara geri atarız.
Gras Double

1
Güzel özet! Lütfen cevabımı yeni PHP 7.3 kullanarak ekleyin . $array[array_key_last($array)];Benchmark için işlev . Ve bittiğinde lütfen bana biraz bildirimde bulun. Performans sonuçlarını karşılaştırmalı olarak görmek istiyorum.
Quasimodo'nun klonu

2
@sz çoğunlukla inatçılık ve sabırla üretildi, ancak Sublime metin editörünün genel seçim ve çok satırlı düzenleme işlevleri yardımcı oldu. rejenerasyon neredeyse bir gün sürdü, bu yüzden tekrar yapmam gerekirse muhtemelen 210 liman işçisinin icrasının çıktısını otomatik olarak bir tabloya dönüştüren bir şey yazacağım :-)
Paul van Leeuwen

1
@ quasimodos-clone En son yayınlanan PHP 5, 7 ve RC'nize dayanarak tüm tabloyu yeniden oluşturdum. Sanırım Aralık ayında piyasaya sürüldükten sonra tekrar üretmek isteyeceğiz. Bu yeni işlevi herkesin dikkatine sunduğunuz için teşekkür ederiz.
Paul van Leeuwen

487

Deneyin

$myLastElement = end($yourArray);

Sıfırlamak için (teşekkürler @hopeseekr):

 reset($yourArray);

Bağlantı kılavuzu

@David Murdoch ekledi: $myLastElement = end(array_values($yourArray));// and now you don't need to call reset(). E_STRICT'de bu uyarı veriyor

Strict Standards: Only variables should be passed by reference

Teşekkürler o_O Tync ve herkese!


38
Kullanın $myLastElement = end(array_values($yourArray));ve şimdi aramanıza gerek yok reset().
David Murdoch

5
@DavidMurdoch Belki de, ama RAM ve CPU'yu çalkalayarak dizi değerleri için geçici dizi yaratır ...
Theodore R. Smith

12
Sunucunuz çok fazla RAM tüketiyorsa, basit bir ekstra işlev çağırmanın bir anlaşma kırıcı olması durumunda, sunucunuzun yapılandırmasını ve kaynaklarını yeniden incelemenizi öneririz.
Chris Baker

3
end(array_values())bir E_STRICT verecektir: "Sadece değişkenler referans ile
geçilmelidir

32
Katı uyarıyı önlemek için ek parantez ekleyin:end((array_values($yourArray)))
Daniel W.

212

Kısa ve güzel.

Hata mesajını kaldırmak ve tek katmanlı formu ve verimli performansı korumak için bir çözüm buldum:

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

- önceki çözüm

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

Not: Ek parantezler a PHP Strict standards: Only variables should be passed by reference.


31
Tam 5 yıl, 6 ay ve 2 gün sonra, daha üstün bir cevap gönderdiniz !! Teşekkür ederim! ve Stack Overflow teşekkür !!
Theodore R. Smith

1
Selamlıyorum, ama ekstra parantez eklemek biraz hackisch geliyor. Ayrıca phpStorm bunu bir hata olarak işaretleyecektir. Ekstra parantez eklemek için ek bilgi ( phpsadness.com/sad/51 ). Hatanın üstesinden gelmek için bunu bir '2-liner' yapabilirsiniz: $array = array_slice($array, -1); $lastEl = array_pop($array);Şahsen ben bunun daha iyi olduğunu düşünüyorum (ayrıştırıcı 'hata' olmadan)
Maurice

3
Dereferencing'i şu şekilde kullanabilirsiniz: array_slice ($ array, -1) [0]
Vikash

1
Dizide dizin olarak dizeleriniz varsa yapamazsınız
rolacja

3
Bu yanıt PHP bildirimlerini önlemek için hala en az iki kontrole ihtiyaç duyar. 1. olmadığını kontrol array_size() > 1 2. dizi aslında bir dizi ise kontrol edin. PHP'nin yerleşik end()işlevi zaten tüm zor işleri daha verimli bir şekilde yaptığı için @Iznogood'un cevabına hala bağlıyım .
Ema4rl

37

Sorun nedir array_slice($array, -1)? (Bkz. Kılavuz: http://us1.php.net/array_slice )

array_slice()bir dizi döndürür. Muhtemelen aradığın şey değil. Elemanı istiyorsunuz.


21
array_slice($array, -1)[0]Elemanı almak için kullanın .
Pang

2
Cevap bu. "end" Dizinin dahili işaretçisini değiştiriyor musunuz? Sorun sormak ve okumak çok zor!
Gerard ONeill

@Pang'ın belirttiği gibi, bu tam değil. reset(array_slice($array, -1))başka bir yaklaşımdır ( array_slice()tek elemanlı bir diziden "küçük" bir şey döndürürse hataya neden olmaz )
rinogo

Öğeyi doğrudan değiştirebileceğinizden en iyi yaklaşım:array_slice($array, -1)[0] = "";
HAlex

20

Referans by-pass hatalarından kaçınmanın bir yolu (örn. "End (dizi_değerleri ($ foo))") call_user_func veya call_user_func_array kullanmaktır:

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

Harika bir yaklaşım! (buraya 'Bu kabul edilen cevap olmalıdır' standardını girin)
Yazım hatası

3
Ya da sadece ekstra bir parantez ekleyin. Daha kısa ve daha tatlı:end((array_values($yourArray)))
Dzhuneyt

4
Ekstra parantez numarası PHP'deki bir hataya dayanır ve bu yaklaşım artık PHP'nin sonraki sürümlerinde (veya en azından PHP 7'de değil) çalışmaz.
Matt Browne

1
Ve call_user_funchile PHP 7'de de çalışmıyor. Bence geçici bir değişken yaratma konusunda sıkıştın.
Matt Browne

15

Dahili işaretçiyi değiştirmeyi umursamıyorsanız (hem dizine eklenen hem de ilişkilendirilebilir dizileri destekler):

// false if empty array
$last = end($array);

// null if empty array
$last = !empty($array) ? end($array) : null;


Dahili işaretçiyi değiştirmeyen bir yardımcı program işlevi istiyorsanız (dizi değere göre iletildiğinden ve işlev bir kopyası üzerinde çalıştığından):

function array_last($array) {
    if (empty($array)) {
        return null;
    }
    return end($array);
}

PHP'nin "anında" kopyalar ürettiğini, yani yalnızca gerçekten gerektiğinde kopyaladığını unutmayın. end()Kendisi dizi, bu nedenle içten dizinin bir kopyası oluşturulur değiştirir.


Bu nedenle, aşağıdaki alternatif aslında diziyi kopyalamadığı için sadece daha hızlıdır, sadece bir dilim yapar:

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

Bu "foreach / return", ilk (ve burada tekli) öğeyi verimli bir şekilde almak için yapılan bir değişikliktir.


Son olarak, yalnızca dizinlenmiş diziler için en hızlı alternatif:

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



Kayıt için, dizinin ilk öğesi için benim başka bir cevabım .


bir array_lastişlev için 2 alternatif uygulama sağlarsınız. Birincisi $arrayiçin kopyalandığını ve ikincisi için kopyalanmadığını belirtirsiniz. Fark nerede / neden ikinci uygulamada değil, ilk uygulamada kopyalanıyor?
Paul van Leeuwen

1
@PaulvanLeeuwen Neden kafanız karıştığını anladım. Cevabı açıklığa kavuşturmaya çalıştım , daha iyi mi?
Gras Double

10

denenmemiş: bu işe yaramaz mı?

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

Array_values ​​tarafından döndürülen dizi geçici olduğundan, hiç kimse işaretçinin sıfırlanıp sıfırlanmadığını umursamıyor.

ve onunla gitmek için anahtara ihtiyacınız varsa sanırım bunu yaparsınız:

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

9

Ben yığınları ile başa çıkmak için bu oldukça sık ihtiyacım var ve her zaman kendimi şaşkın bulmak dizisi veya herhangi bir biçimde iç işaretçisini manipüle etmeden hiçbir yerel işlevi yoktur.

Bu yüzden genellikle ilişkisel dizilerde de kullanımı güvenli bir util işlevi taşırım.

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

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

1
İyi haber, yerel bir işlev yapıyorlar :-) Burada yayın planlamasına göz atabilirsiniz : wiki.php.net/todo/php73 (bu yazı sırasında 13 Aralık 2018'de bekleniyor).
Paul van Leeuwen

9

Bir dizinin son öğesini almak için şunu kullanın:

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

Karşılaştırma

1000 kez yineledim, sırasıyla 100 ve 50.000 eleman içeren küçük ve büyük dizilerin son elemanını yakaladım.

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 Sürüm 5.5.32 kullandım.


$ dizi [dizi_anahtarları ($ dizi) [sayım (dizi_anahtarlar ($ dizi)) - 1]] kullanmaya ne dersiniz?
user2782001

hmm..array_keys oldukça zayıf bir şekilde ölçekleniyor gibi görünüyor.
user2782001

1
Büyük dizinin (0.0002) öğeyi açıp tekrar koyması daha çılgınca ... $ val = $ ar [] = $ array_pop ($ ar);
user2782001

1
@ Westy92 Birimleriniz temel ölçütte yanlış görünüyor. Verdiğiniz en küçük sayı yaklaşık 0.3 nanosaniye olan 0.00031 ... mikrosaniye . Bu, yeni bir bilgisayarınız varsa, testinizin çalışması için bir saat işareti aldığı anlamına gelir. Sanırım ya milisaniye, hatta saniye bile demek istedim .
cesoid

1
Değerler açıkça birkaç büyüklük sırası yanlıştır. Neden performansa odaklanmalıyım?
istepaniuk

6

end (), bir dizinin son öğesini sağlayacaktır

$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
Bu çözüm çalışır, ancak dizinin iç işaretçisini değiştirir, doğru yol olduğunu düşünmüyorum.
UnixAgain

5

PHP sürümü 7.3 fonksiyonları itibariyle array_key_firstve array_key_lasttanıtıldı.

PHP'deki diziler katı dizi türleri olmadığı için, yani dizin 0'dan başlayan sabit boyutlu alanların sabit boyutlu koleksiyonları, ancak dinamik olarak genişletilmiş ilişkisel dizi olduğundan, bilinmeyen anahtarlarla konumların işlenmesi zordur ve geçici çözümler çok iyi performans göstermez. Buna karşılık, gerçek diziler dahili olarak işaretçi aritmetikleri yoluyla çok hızlı bir şekilde ele alınacak ve son indeks derleme zamanında deklarasyon ile bilinmektedir.

En azından ilk ve son konumdaki sorun, 7.3 sürümünden bu yana yerleşik işlevlerle çözüldü. Bu , kutudan çıkarılmış dizi değişmezleri üzerinde herhangi bir uyarı olmadan bile çalışır :

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

Açıkçası son değer :

$array[array_key_last($array)];

1
Bunu herkesin dikkatine sunduğunuz için teşekkürler. Bunu kullanmaya istekli olanlar için: lütfen bu yazının yapıldığı anda bunun bir RC olduğunu unutmayın. Aralık 2018'de piyasaya sürülmesi planlanıyor.
Paul van Leeuwen

1
Bu harika bir haber. Aşağıdaki yanıta çok amaçlı bir dolgu / dolgu gönderdim, böylece insanlar bu sözdizimini hemen kullanmaya başlayabilirler.
Mark Thomson

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

$ Dizi işaretçileri üzerinde hiçbir değişiklik yapılmaz. Bu,

reset($array)

bazı durumlarda istenmeyebilir.


3

Benim için:

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

İlişkilendirmelerle:

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

Lütfen cevabınıza bir bağlam sağlayın.
Shawn

2
@Shawn Hangi bağlam? Bağlama gerek yok. İlişkilendirilebilir diziler için kod eklendi.
Mirko Pagliai

3

En iyi cevaplar harika, ancak @ paul-van-leeuwen ve @ quasimodos-clone tarafından belirtildiği gibi, PHP 7.3 bu sorunu doğrudan çözmek için iki yeni işlev sunacaktır - array_key_first () ve array_key_last () .

Bu sözdizimini bugün aşağıdaki çoklu dolgu (veya dolgu) işlevleriyle kullanmaya başlayabilirsiniz.

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

Dikkat: Bu, PHP 5.4 veya üstünü gerektirir.


2

Bunu yapmak ve dizinin dahili işaretçisini karıştırmamak için E_STRICT'den kaçınmak için şunları kullanabilirsiniz:

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

$last_element = lelement($array);

lelement yalnızca bir kopyayla çalışır, böylece dizinin işaretçisini etkilemez.


2

Başka bir çözüm:

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

2

Bir olası çözüm daha ...

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

İlişkilendirilebilir diziler üzerinde çalışmamak bana intikam almak için yeterli bir neden gibi görünmüyor. Kalite açısından bu cevap, bu sorunun diğer cevaplarından daha kötü değildir. Şu anda neden en az 2 downvotes gördüğümü anlamıyorum. (-2 puanı). Her neyse, benim için oy, o kadar da kötü değil.
Paul van Leeuwen

2

Nasıl olur:

current(array_slice($array, -1))
  • çağrışımlı diziler için çalışır
  • ne zaman çalışır $array == [](döner false)
  • orijinal diziyi etkilemez

2

Aşağıdaki mantığı kullanarak bir dizideki son öğeyi kolayca alacaksınız

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

Sadece son eleman değil, aynı zamanda aşağıdaki mantığı kullanarak ikinci son, üçüncü son ve benzerlerini de alabilirsiniz.

ikinci son eleman için yukarıdaki ifadede sadece 2 sayısını geçmeniz gerekir, örneğin:
echo ($ array [count ($ array) -2]);


1

Diziden son değeri almak için:

array_slice($arr,-1,1) ;

Son değer form dizisini kaldırmak için:

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

1
array_slice($arr,-1,1)son elemanla değil, uzunluk 1 ile başka bir diziyle sonuçlanır
Vic

Bir örnek verelim: $a=array("red","green","blue","yellow","brown"); print_r(array_slice($a,-1,1)); Sonuç:Array ( [0] => brown )
Rishabh

1

basitçe: $last_element = end((array_values($array)))

Diziyi sıfırlamaz ve STRICT uyarıları vermez.

PS. En çok oy verilen cevap hala çift parantez olmadığından, bu cevabı gönderdim.


1

Bence bu mevcut cevapların tamamında küçük bir gelişme:

$lastElement = count($array) > 0 ? array_values(array_slice($array, -1))[0] : null;
  • Özellikle büyük dizilerde end()kullanılanlardan daha iyi performans veya çözümlerarray_keys()
  • Dizinin dahili işaretçisini değiştirmeyecek
  • Boş diziler için tanımlanmamış bir ofsete erişmeye çalışmaz
  • Boş diziler, dizinlenmiş diziler, karışık diziler ve ilişkilendirilebilir diziler için beklendiği gibi çalışır

Ne yazık ki, ilişkilendirilebilir dizilerle çalışmaz, çünkü dilimin tek öğesinin adlandırılmış bir anahtarı olabilir.
Gras Double

Haklısın, bir düzeltme eklemek için düzenlendi ( array_valuestek elementli dilimde)
Adelmar


1

Bugünlerde, bir php.net/end cevabında önerildiği gibi, her zaman bu yardımcıya sahip olmayı tercih ederim .

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

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

Bu, işaretçiyi her zaman olduğu gibi tutacaktır ve asla parantez, katı standartlar veya herhangi bir şey hakkında endişelenmemiz gerekmeyecektir.


Yukarıda sözü edilen: stackoverflow.com/a/45333947/1255289
miken32


-1

Dizinin son öğesini dizisinin döngüsünün içine almak isterseniz ne olur?

Aşağıdaki kod sonsuz bir döngüye neden olacaktır:

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

Çözüm, ilişkisel olmayan diziler için açıktır:

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

2
End () ve reset () fonksiyonlarını biliyorum. Yorumum, foreach gibi döngülerle veya bu işlevleri kullanamayacağınız zamanla ilgiliydi, çünkü reset fonksiyonu yineleme için döngüde kullanılan bir dizinin iç işaretçisini sıfırlar. Maalesef, soru daha basitti, sadece projemde karşılaştığım daha gelişmiş bir durum vermek istedim. Saygılarımla.
Vadim Podlevsky

Bu birçok yönden yanlıştır (yinelenen diziler, katı olmayan karşılaştırma ...) ve her durumda soru ile gerçekten ilgili değildir.
Tgr

son öğeyi almak için end ($ array) işlevini kullanın, neden gereksiz yere döngüler kullanıyorsunuz?
Mahak Choudhary

1
@MahakChoudhary Benim yorumum "zaten bu dizinin bir döngü içinde bazı manipülasyonlar yapıyorsanız dizinin son elemanını almak için bir ektir. End () kullanarak innver işaretçisini sıfırlayacak ve yineleme döngü kırmak. Şerefe!
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;
}



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.