İlişkilendirilebilir bir dizideki ilk anahtar alınsın mı?


756

Olası ilişkilendirilebilir bir dizideki ilk anahtarı belirlemenin en iyi yolu nedir? Benim ilk dizi sadece foreach ve hemen sonra, böyle kırma düşündüm:

foreach ($an_array as $key => $val) break;

Bu nedenle $ anahtarına sahip olmak ilk anahtarı içerir, ancak bu verimsiz görünür. Daha iyi bir çözümü olan var mı?


4
Verimsiz neden öngörüldür?
Emilio Gort

2
Tüm cevaplarla karşılaştırıldığında, foreach hala en hızlı FIDDLE, PHP 5.3 , PHP 5.5'teki localhost testi, farkın biraz foreach lehine olduğunu gösteriyor.
Danijel

3
@Danijel, foreachanlamsal olarak yanlış.
Pacerier

2
@AlexS, Ya çalışır each($arr)['key']ya each($arr)[0]da çalışır.
Pacerier

1
@Danijel Artık yok ... anahtar:, 0.0107foreach:0.0217
SeanJA

Yanıtlar:


1337

2019 Güncellemesi

PHP 7.3'ten başlayarak array_key_first(), dahili işaretçiyi sıfırlamadan verilen diziden ilk anahtarı alacak olan yeni bir yerleşik işlev vardır. Daha fazla bilgi için belgelere bakın.


Sen kullanabilirsiniz resetve key:

reset($array);
$first_key = key($array);

Temel olarak ilk kodunuzla aynıdır, ancak biraz daha az yük ile ve ne olduğu daha açıktır.

Aramayı unutmayın reset, yoksa dizideki anahtarlardan herhangi birini alabilirsiniz. Ayrıca kullanabilirsiniz endyerine resetgeçen anahtarı almak için.

Anahtarın ilk değeri almasını istiyorsanız, resetaslında değeri döndürür:

$first_value = reset($array);

Yine de dikkat edilmesi gereken özel bir durum vardır (bu yüzden önce dizinin uzunluğunu kontrol edin):

$arr1 = array(false);
$arr2 = array();
var_dump(reset($arr1) === reset($arr2)); // bool(true)

141
Bir yan not olarak, reset()herhangi bir dizinin ilk öğesini (değer değil, anahtar) da döndürür, bu da kullanışlı olabilir.
devios1

5
Dokümanlarda ilişkilendirilebilir bir dizinin ilk değerini almak için reset () ` reset()diyen bir yorum var Don't use . Gerçek diziler için harika çalışıyor, ancak Iterator nesnelerinde beklenmedik bir şekilde çalışıyor. bugs.php.net/bug.php?id=38478 `Bu hala doğru mu? Kafam karıştı
Dmitry Pashkevich

13
@DmitryPashkevich: Bu yorum için endişelenme. arrayNesneler hakkında değil , özel nesneler (gerçek diziler olmayan) hakkında konuşuyorlar . Sanırım veri yapılarında fark var, ama temelde, resetnesneler $propiçin "hata" raporunda verilen örnekte olacak ilk "anahtar" değerini döndürür , ancak bir dizi için ilk anahtar. Endişelenmeyin, gerçek diziler (ile oluşturulmuş array(…)) kullandığınız sürece sorun yaşamayacaksınız.
Blixt

2
End () ve reset () 'in bir yan etkisi olduğu belirtilmelidir. Bununla birlikte, dünyadaki çoğu kod, herhangi bir yerde olan dahili işaretçiye dayanmaz, bu nedenle bu genellikle bir sorun değildir.
Mart'ta donquixote

1
@ user3019105 sizin fonksiyonu dışında herhangi bir kod (arayarak değiştirirse o dizinin başına yalnızca bir iç işaretçi, araç yoktur next, reset, endveya dizinin döngü) Aradığınızda, beklenen değer almazsınız key. Yani evet, istediğinizi aldığınızdan emin olmak için her zaman resetkullanmadan önce arayın key.
Blixt

80

array_keysbir dizi anahtar döndürür. İlk girişi alın. Alternatif olarak, resetdiziyi arayabilir ve daha sonra key. İkinci yaklaşım muhtemelen biraz daha hızlıdır (Test etmediğimi sanıyordum), ancak dahili işaretçiyi sıfırlamanın yan etkisi vardır.


52
Bunun gelecekteki okuyucuları için sadece (geç) bir not: İkinci yaklaşım sadece "biraz" daha hızlı değildir. Tüm diziyi yineleme, yeni oluşturulmuş başka bir dizide her anahtarı saklama ve dizinin ilk anahtarını dize olarak isteme arasında büyük bir fark vardır.
Blixt

3
Operasyonda soruda olduğu gibi neden verimsiz öngörü tüm bu cevaplarla karşılaştırılıyor?
Emilio Gort

5
@EmilioGort Güzel soru. Aslında foreach+ breakve reset+ ' nın performansında herhangi bir fark olduğunu sanmıyorum key. Ama birincisi oldukça garip görünüyor, bu yüzden stilistik konular için ikincisini tercih ederim.
troelskn

@EmilioGort: Afaik, foreach () diziyi dahili olarak kopyalar. Bu yüzden daha yavaş olduğunu varsayabiliriz. (Birisi bunu teyit edebilirse iyi olurdu)
donquixote

3
@donquixote Emin değilim, ama normal bir dizi (ve bir tür veya yineleyici arabirimi uygulayan bir nesne değil) varsayarsak, bunun foreachiçin dahili bir kopya oluşturmadığından eminim , sadece bir işaretçi tekrarlar Ayrıntılı düşük seviyeli kullanmaya benzer next, currentvb
troelskn

54

İlginçtir ki, foreach döngüsü bunu yapmanın en etkili yoludur.

OP özellikle verimlilik hakkında sorduğundan, mevcut tüm cevapların aslında bir foreach'tan çok daha az verimli olduğuna dikkat edilmelidir.

Ben php 5.4 ile bu konuda bir kriter yaptım ve sıfırlama / anahtar işaretçi yöntemi (kabul edilen cevap) bir foreach yaklaşık 7 kat daha yavaş görünüyor. Tüm diziyi (dizi_anahtarları, dizi_flip) manipüle eden diğer yaklaşımlar bundan daha yavaştır ve büyük bir dizi ile çalışırken çok daha kötü hale gelir .

Foreach hiç verimsiz değil, kullanmaktan çekinmeyin!

2015-03-03 Düzenle:

Karşılaştırma komut dosyaları istendi, orijinal olanlarım yok, bunun yerine yeni testler yaptım. Bu kez foreach'ı reset / key'den sadece iki kat daha hızlı buldum. 100 tuşlu bir dizi kullandım ve fark edilir bir fark elde etmek için her yöntemi milyon kez çalıştırdım, işte basit karşılaştırmanın kodu:

$array = [];
for($i=0; $i < 100; $i++)
    $array["key$i"] = $i;

for($i=0, $start = microtime(true); $i < 1000000; $i++) {
    foreach ($array as $firstKey => $firstValue) {
        break;
    }
}
echo "foreach to get first key and value: " . (microtime(true) - $start) . " seconds <br />";

for($i=0, $start = microtime(true); $i < 1000000; $i++) {
    $firstValue = reset($array);
    $firstKey = key($array);
}
echo "reset+key to get first key and value: " . (microtime(true) - $start) . " seconds <br />";

for($i=0, $start = microtime(true); $i < 1000000; $i++) {
    reset($array);
    $firstKey = key($array);
}
echo "reset+key to get first key: " . (microtime(true) - $start) . " seconds <br />";


for($i=0, $start = microtime(true); $i < 1000000; $i++) {
    $firstKey = array_keys($array)[0];
}
echo "array_keys to get first key: " . (microtime(true) - $start) . " seconds <br />";

Benim php 5.5 bu çıktılar:

foreach to get first key and value: 0.15501809120178 seconds 
reset+key to get first key and value: 0.29375791549683 seconds 
reset+key to get first key: 0.26421809196472 seconds 
array_keys to get first key: 10.059751987457 seconds

sıfırla + anahtar http://3v4l.org/b4DrN/perf#tabs
foreach http://3v4l.org/gRoGD/perf#tabs


3
Bir yerde kriterler var mı? Nasıl test ettiğiniz gibi. Her neyse, onları çalıştırdığınız için teşekkür ederiz!
grip

Tüm test boyunca kullanılan aynı dizi olduğunu gerçeğe işaret etmek istiyorum. Bu gerçeğin öngörü yaklaşımını önemli ölçüde etkilediğini düşünüyorum. @ Donquixote'un yukarıdaki bazı yanıtlara yorumunda belirtildiği gibi - foreach diziyi dahili olarak kopyalar. Dizi kopyalamasından kaçınmak sadece bu testte performansı arttırdığından, bu kopyanın karşılaştırmalı değerlendirmeyi tekrar kullandığını düşünebilirim.
Jarda

2
@Jarda php7'den itibaren foreachforeach döngüsünün içinde doğrudan değiştirmedikçe diziyi asla kopyalamaz. Php5 üzerinde dizi yapısı (onun refcount> 1 olduğunda) bazı durumlarda kopyalanabilir ve aslında haklısın orada önemli bir etkisi olabilir. Neyse ki php7 hakkında endişelenecek bir şey yok, bu sorunun çözüldüğü yer. İşte 'büyük geçmişte nasıl çalıştığını foreach şimdi başlık altında nasıl çalıştığını hem okuyup s.
Webmut

2
php7.2'den itibaren yukarıdaki ölçütü kullanarak, foreach hala en hızlı
billynoah

36

key($an_array) sana ilk anahtarı verecek

Blixt başına düzenleme: işaretçiyi dizinin başına sıfırlamak için daha reset($array);önce aramanız gerekir key($an_array).


7
Dizinin işaretçisinin ilk öğede olmayabileceğini unutmayın, cevabımı görün.
Blixt

Ben ilk önce dizi sadece bir eleman olduğundan emin olun çünkü bu cevap sıfırlama benim durumumda yardımcı olacağını düşünüyorum. Teşekkürler
groovenectar


22

2018+

için PHP 7.3 ile başlayarak, array_key_first()tam olarak bunu başaran bir işlev vardır:

$array = ['foo' => 'lorem', 'bar' => 'ipsum'];
$firstKey = array_key_first($array); // 'foo'

Belgelere buradan ulaşabilirsiniz . 😉


21
list($firstKey) = array_keys($yourArray);

2
Bu muhtemelen en verimli değil.
Yada

3
@Yada, evet, ancak bu nadir durumlarda fark edilebilir; çoğu durumda okunabilirlik ve bakım kolaylığı çok daha önemlidir; ve ayrıca orijinal nesneleri / dizileri değiştirmeyen çözümü tercih ederim: örn. reset ($ ar); $ anahtar = anahtar ($ ar); - her zaman iyi bir fikir değildir, MartyIX'in benimkinden daha özlü olan çözümünü tercih ederim, örneğin: array_keys ($ ar) [0];
Sergiy Sokolenko

20

Verimlilik sizin için önemli değilse, array_keys($yourArray)[0]PHP 5.4 (ve üstü) sürümlerinde kullanabilirsiniz .

Örnekler:

# 1
$arr = ["my" => "test", "is" => "best"];    
echo array_keys($arr)[0] . "\r\n"; // prints "my"


# 2
$arr = ["test", "best"];
echo array_keys($arr)[0] . "\r\n"; // prints "0"

# 3
$arr = [1 => "test", 2 => "best"];
echo array_keys($arr)[0] . "\r\n"; // prints "1"

Çözüme göre avantaj:

list($firstKey) = array_keys($yourArray);

array_keys($arr)[0]fonksiyon parametresi (yani doSomething(array_keys($arr)[0], $otherParameter)) olarak geçebilmenizdir .

HTH


3
Mu array_keys($arr)[0]sözdizimi geçerlidir?
trante

5
PHP 5.4 sürümündedir. Denir array dereferencing. Örneğin bakınız: schlueters.de/blog/archives/…
Martin Vseticka

@trante, PHP <5.4 hariç güneş altındaki her dilde geçerlidir.
Pacerier

13

Lütfen aşağıdakileri bulun:

$yourArray = array('first_key'=> 'First', 2, 3, 4, 5);
$keys   =   array_keys($yourArray);
echo "Key = ".$keys[0];

Çalışma Örneği:


12
$myArray = array(
    2 => '3th element',
    4 => 'first element',
    1 => 'second element',
    3 => '4th element'
);
echo min(array_keys($myArray)); // return 1

1
@ jurgemaister max()dozu bir doç dizinin ilk anahtarını döndürmez. maksimum liste veya dizi
öğesinin

5
OP isteği değil, ancak bazı durumlarda çok yararlı.
d.raev

9

Bu da bir çözüm olabilir:

$yourArray = array('first_key'=> 'First', 2, 3, 4, 5);
$first_key = current(array_flip($yourArray));
echo $first_key;

Test ettim ve işe yarıyor.

Çalışma Kodu .


3
array_flip (): Yalnızca STRING ve INTEGER değerlerini çevirebilir!
Mauro

5

Webmut çözümünü geliştirmek için aşağıdaki çözümü ekledim:

$firstKey = array_keys(array_slice($array, 0, 1, TRUE))[0];

PHP 7.1 benim için çıktı:

foreach to get first key and value: 0.048566102981567 seconds 
reset+key to get first key and value: 0.11727809906006 seconds 
reset+key to get first key: 0.11707186698914 seconds 
array_keys to get first key: 0.53917098045349 seconds 
array_slice to get first key: 0.2494580745697 seconds 

Bunu 10000 boyutlu bir dizi için yaparsam, sonuçlar olur

foreach to get first key and value: 0.048488140106201 seconds 
reset+key to get first key and value: 0.12659382820129 seconds 
reset+key to get first key: 0.12248802185059 seconds 
array_slice to get first key: 0.25442600250244 seconds 

Array_keys yöntemi 30 saniyede zaman aşımına uğrar (yalnızca 1000 öğeyle, geri kalanı için zamanlama yaklaşık olarak aynıydı, ancak array_keys yöntemi yaklaşık 7.5 saniyeydi).


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

3

Benim için en iyi yöntem

array_shift(array_keys($array))

array_keys ilk diziden anahtar dizisini alır ve ardından array_shiftilk eleman değerini keser. Bunun için PHP 5.4+ sürümüne ihtiyacınız olacak.


3

Bu şimdiye kadar bulduğum daha kolay yol. Hızlı ve sadece iki satır kod :-D

$keys = array_keys($array);
echo $array[$keys[0]];


0

Bir astar:

$array = array('key1'=>'value1','key2'=>'value2','key3'=>'key3');
echo key( array_slice( $array, 0, 1, true ) );

# echos 'key1'

0

Bugün bir POST isteği tarafından döndürülen dizimin ilk anahtarını aramak zorunda kaldım. (Ve form kimliği vb. Numarasını not edin)

Bunu buldum: PHP'de ilişkisel dizinin ilk anahtarını döndür

http://php.net/key

Bunu yaptım ve işe yarıyor.

    $data = $request->request->all();
    dump($data);
    while ($test = current($data)) {
        dump($test);
        echo key($data).'<br />';die();
        break;
    }

Belki başka bir adamın 15 dakikasını çevreleyecektir. CYA.


-2

Dizinizle oynayabilirsiniz

$daysArray = array('Monday', 'Tuesday', 'Sunday');
$day = current($transport); // $day = 'Monday';
$day = next($transport);    // $day = 'Tuesday';
$day = current($transport); // $day = 'Tuesday';
$day = prev($transport);    // $day = 'Monday';
$day = end($transport);     // $day = 'Sunday';
$day = current($transport); // $day = 'Sunday';

Dizinin ilk elemanını kullanabilmek için currentve son eleman için kullanabilirsinizend

Düzenle

Sadece cevap için daha fazla oy almamak uğruna, anahtarınızı array_keysyukarıda gösterildiği gibi kullanarak ve kullanmaya dönüştürebilirsiniz .


1
Bunlar anahtar değil, değerlerdir.
Victor Schröder
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.