Dapatkan kunci pertama dalam array asosiatif (mungkin)?

757

Apa cara terbaik untuk menentukan kunci pertama dalam array asosiatif? Saya pertama kali berpikir untuk hanya melihat array dan kemudian segera memecahnya, seperti ini:

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

Dengan demikian memiliki $ key berisi kunci pertama, tetapi ini tampaknya tidak efisien. Adakah yang punya solusi yang lebih baik?

Alex S
sumber
4
Mengapa pendahuluan tidak efisien?
Emilio Gort
2
Dibandingkan dengan semua jawaban, foreach masih merupakan FIDDLE tercepat , PHP 5.3 , tes localhost saya di PHP 5.5 menunjukkan bahwa perbedaannya sedikit lebih mendukung foreach.
Danijel
3
@Danijel, foreachsecara semantik salah.
Pacerier
2
@AlexS, Baik each($arr)['key']atau each($arr)[0]mau bekerja.
Pacerier
1
@Danijel Tidak lagi ... kunci 0.01070.0217
:,

Jawaban:

1338

Pembaruan 2019

Mulai dari PHP 7.3 , ada fungsi built-in baru array_key_first()yang disebut yang akan mengambil kunci pertama dari array yang diberikan tanpa mengatur ulang pointer internal. Lihatlah dokumentasi untuk informasi lebih lanjut.


Anda dapat menggunakan resetdan key:

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

Ini pada dasarnya sama dengan kode awal Anda, tetapi dengan sedikit overhead, dan lebih jelas apa yang terjadi.

Hanya ingat untuk menelepon reset, atau Anda bisa mendapatkan salah satu kunci dalam array. Anda juga dapat menggunakan endalih-alih resetuntuk mendapatkan kunci terakhir.

Jika Anda ingin kunci untuk mendapatkan nilai pertama, resetsebenarnya kembalikan:

$first_value = reset($array);

Ada satu kasus khusus yang harus diperhatikan (jadi, periksa panjang array terlebih dahulu):

$arr1 = array(false);
$arr2 = array();
var_dump(reset($arr1) === reset($arr2)); // bool(true)
Blixt
sumber
141
Sebagai catatan, reset()juga terjadi untuk mengembalikan elemen pertama (nilai, bukan kunci) dari array apa pun, yang dapat berguna juga.
devios1
5
Ada komentar di dokumen untuk reset()mengatakan Don't use reset () `untuk mendapatkan nilai pertama dari array asosiatif. Ini berfungsi bagus untuk array yang benar tetapi bekerja secara tidak terduga pada objek Iterator. bugs.php.net/bug.php?id=38478 `Apakah itu masih benar? Saya bingung
Dmitry Pashkevich
13
@DmitryPashkevich: Jangan khawatir tentang komentar itu. Mereka tidak berbicara tentang arrayobjek, tetapi objek khusus (yang bukan array sebenarnya). Saya kira mereka mendapat perbedaan dalam struktur data bingung, tetapi pada dasarnya, resetmengembalikan nilai "kunci" pertama, yang untuk objek akan menjadi $propdalam contoh yang diberikan dalam laporan "bug", tetapi untuk array kunci pertama. Jadi jangan khawatir, selama Anda menggunakan array nyata (dibuat dengan array(…)), Anda tidak akan punya masalah.
Blixt
2
Harus disebutkan bahwa end () dan reset () memiliki efek samping. Namun, sebagian besar kode di dunia tidak bergantung pada pointer internal yang ada di mana saja, jadi ini umumnya tidak menjadi masalah.
donquixote
1
@ user3019105 Hanya ada satu pointer internal yang per array, yang berarti bahwa jika ada kode di luar fungsi Anda perubahan itu (dengan menelepon next, reset, endatau perulangan melalui array), Anda tidak akan mendapatkan nilai yang diharapkan ketika Anda menelepon key. Jadi ya, selalu telepon resetsebelum menggunakan keyuntuk memastikan Anda mendapatkan yang Anda inginkan.
Blixt
80

array_keysmengembalikan array kunci. Ambil entri pertama. Atau, Anda bisa memanggil resetarray, dan selanjutnya key. Pendekatan terakhir mungkin sedikit lebih cepat (Thoug saya tidak mengujinya), tetapi memiliki efek samping mengatur ulang pointer internal.

troelskn
sumber
52
Hanya sebuah catatan (terlambat) untuk pembaca masa depan tentang hal ini: Pendekatan yang terakhir tidak hanya "sedikit" lebih cepat. Ada perbedaan besar antara iterasi seluruh array, menyimpan setiap kunci di array lain yang baru dibuat, dan meminta kunci pertama dari array sebagai string.
Blixt
3
Mengapa pendahuluan yang tidak efisien seperti op dalam pertanyaan dibandingkan dengan semua jawaban ini?
Emilio Gort
5
@ EmilioGort Pertanyaan bagus. Saya tidak berpikir ada perbedaan dalam kinerja foreach+ breakdan reset+ keysebenarnya. Tapi yang pertama terlihat agak aneh, jadi untuk masalah gaya, saya lebih suka yang terakhir.
troelskn
@EmilioGort: Afaik, foreach () menyalin array secara internal. Jadi kita bisa menganggapnya lebih lambat. (Akan lebih baik jika seseorang dapat mengonfirmasi hal itu)
donquixote
3
@donquixote Saya tidak tahu pasti, tetapi dengan asumsi itu adalah array biasa (dan bukan objek yang mengimplementasikan beberapa jenis atau antarmuka Iterator), saya cukup yakin foreachtidak membuat salinan internal untuk itu, melainkan hanya mengulang pointer. , mirip dengan menggunakan level yang lebih rendah next, currentdll.
troelskn
54

Cukup menarik, loop foreach sebenarnya adalah cara paling efisien untuk melakukan ini.

Karena OP secara khusus bertanya tentang efisiensi, harus ditunjukkan bahwa semua jawaban saat ini sebenarnya jauh lebih efisien daripada pendahuluan.

Saya melakukan benchmark dengan php 5.4, dan metode reset / pointer kunci (jawaban yang diterima) tampaknya sekitar 7 kali lebih lambat daripada foreach. Pendekatan lain yang memanipulasi seluruh array (array_keys, array_flip) jelas bahkan lebih lambat dari itu dan menjadi lebih banyak lebih buruk ketika bekerja dengan array besar.

Foreach sama sekali tidak efisien, jangan ragu untuk menggunakannya!

Edit 2015-03-03:

Skrip benchmark telah diminta, saya tidak punya yang asli tetapi membuat beberapa tes baru sebagai gantinya. Kali ini saya menemukan foreach hanya sekitar dua kali lebih cepat dari reset / kunci. Saya menggunakan array 100-kunci dan menjalankan setiap metode sejuta kali untuk mendapatkan beberapa perbedaan nyata, inilah kode tolok ukur sederhana:

$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 />";

Pada php saya 5.5 output ini:

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

reset + key http://3v4l.org/b4DrN/perf#tabs
foreach http://3v4l.org/gRoGD/perf#tabs

Webmut
sumber
3
Apakah Anda memiliki tolok ukur di suatu tempat. Seperti cara Anda menguji dll. Pokoknya, terima kasih telah menjalankannya!
Flu
Saya ingin menunjukkan fakta, bahwa ada array yang sama digunakan melalui seluruh tes. Saya pikir fakta ini secara signifikan memengaruhi pendekatan pendahuluan. Seperti @donquixote disebutkan dalam komentar atas beberapa respons di atas - foreach secara internal menyalin array. Saya bisa membayangkan bahwa salinan ini digunakan kembali saat menjalankan patokan karena menghindari penyalinan array meningkatkan kinerja hanya dalam tes ini.
Jarda
2
@ Jarda Pada php7, foreachjangan pernah menyalin array kecuali Anda langsung memodifikasinya di dalam foreach loop. Pada php5 struktur array dapat disalin dalam beberapa kasus (ketika refcount> 1) dan Anda benar itu bisa menjadi pengaruh yang signifikan di sana. Untungnya tidak ada yang perlu dikhawatirkan di php7, di mana masalah ini diselesaikan. Berikut ini adalah bacaan yang bagus tentang bagaimana foreach bekerja di bawah tenda sekarang dan bagaimana cara kerjanya di masa lalu.
Webmut
2
pada php7.2 menggunakan tolok ukur di atas, foreach masih tercepat
billynoah
36

key($an_array) akan memberi Anda kunci pertama

edit per Blixt: Anda harus memanggil reset($array);sebelumnya key($an_array)untuk mengatur ulang pointer ke awal array.

jimyi
sumber
7
Ingat bahwa pointer array mungkin bukan pada elemen pertama, lihat jawaban saya.
Blixt
Saya pikir jawaban ini akan membantu kasus saya tanpa mengatur ulang karena saya pertama-tama memastikan array hanya memiliki satu elemen. Terima kasih
groovenectar
23

Kamu bisa mencoba

array_keys($data)[0]
Sumbat
sumber
22

Untuk 2018+

Dimulai dengan PHP 7.3, ada array_key_first()fungsi yang mencapai hal ini:

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

Dokumentasi tersedia di sini . 😉

ivanaugustobd
sumber
21
list($firstKey) = array_keys($yourArray);
Sergiy Sokolenko
sumber
2
Ini mungkin bukan yang paling efisien.
Yada
3
@Yada, ya, tapi ini mungkin terlihat dalam kasus yang jarang terjadi; dalam banyak kasus keterbacaan dan pemeliharaan adalah jauh lebih penting; dan saya juga lebih suka solusi yang tidak bermutasi objek / array asli: misalnya reset ($ ar); $ key = key ($ ar); - tidak selalu ide yang baik, saya lebih suka memilih solusi MartyIX yang lebih ringkas daripada milik saya, misalnya: array_keys ($ ar) [0];
Sergiy Sokolenko
20

Jika efisiensi tidak terlalu penting bagi Anda, Anda dapat menggunakannya array_keys($yourArray)[0]dalam PHP 5.4 (dan lebih tinggi).

Contoh:

# 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"

Keuntungan dibandingkan solusi:

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

adalah bahwa Anda dapat lulus array_keys($arr)[0]sebagai parameter fungsi (misdoSomething(array_keys($arr)[0], $otherParameter) ).

HTH

Martin Vseticka
sumber
3
Apakah array_keys($arr)[0]sintaksis valid?
trante
5
Itu dalam PHP 5.4. Itu disebut array dereferencing. Lihat misalnya: schlueters.de/blog/archives/…
Martin Vseticka
@trante, Ini berlaku di setiap bahasa di bawah matahari kecuali PHP <5.4.
Pacerier
13

Silakan temukan yang berikut ini:

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

Contoh kerja:

Murid
sumber
12
$myArray = array(
    2 => '3th element',
    4 => 'first element',
    1 => 'second element',
    3 => '4th element'
);
echo min(array_keys($myArray)); // return 1
Hamidreza
sumber
1
@jurgemaister max()dosis tidak mengembalikan kunci pertama dari array assoc. max mengembalikan nilai maksimum daftar atau item array
Hamidreza
5
Bukan permintaan OP, tetapi sangat berguna dalam beberapa situasi.
d.raev
9

Ini juga bisa menjadi solusi:

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

Saya telah mengujinya dan berfungsi.

Kode Kerja .

Murid
sumber
3
array_flip (): Hanya dapat membalik nilai STRING dan INTEGER!
Mauro
5

Untuk menyempurnakan solusi Webmut , saya telah menambahkan solusi berikut:

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

Output untuk saya di PHP 7.1 adalah:

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 

Jika saya melakukan ini untuk array ukuran 10.000, maka hasilnya menjadi

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 

Metode array_keys waktu 30 detik (dengan hanya 1000 elemen, waktu untuk sisanya hampir sama, tetapi metode array_keys memiliki sekitar 7,5 detik).

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

Cara terbaik yang berhasil bagi saya adalah

array_shift(array_keys($array))

array_keys mendapat larik kunci dari larik awal dan kemudian array_shiftmemotong darinya nilai elemen pertama. Anda akan membutuhkan PHP 5.4+ untuk ini.

Yuriy Petrovskiy
sumber
3

Ini adalah cara termudah yang pernah saya temukan. Cepat dan hanya dua baris kode :-D

$keys = array_keys($array);
echo $array[$keys[0]];
Salvi Pascual
sumber
2

php73:

$array = ['a' => '..', 'b' => '..'];

array_key_first($array); // 'a'
array_key_last($array); // 'b';

http://php.net/manual/en/function.array-key-first.php

Benjamin Beganović
sumber
1
Memasukkan penjelasan sangat membantu untuk meningkatkan kualitas posting Anda. Ingatlah bahwa Anda menjawab pertanyaan untuk pembaca di masa depan, dan orang-orang itu mungkin tidak tahu alasan untuk saran kode Anda
MichaelvE
0

Satu kalimat:

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

# echos 'key1'
Kohjah Breese
sumber
0

Hari ini saya harus mencari kunci pertama dari array saya yang dikembalikan oleh permintaan POST. (Dan catat nomor untuk id formulir dll)

Yah, saya telah menemukan ini: Kembalikan kunci pertama array asosiatif di PHP

http://php.net/key

Saya sudah melakukan ini, dan itu berhasil.

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

Mungkin itu akan lebih baik dari pria lain. CYA.

Roupioz Clement
sumber
-2

Anda dapat bermain dengan array Anda

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

Untuk mendapatkan elemen pertama array yang dapat Anda gunakan currentdan untuk elemen terakhir Anda dapat menggunakanend

Edit

Demi tidak mendapatkan suara turun lagi untuk jawaban, Anda dapat mengonversi kunci Anda untuk menggunakan array_keysdan menggunakan nilai seperti yang ditunjukkan di atas.

Priyank
sumber
1
Ini adalah nilai, bukan kunci.
Victor Schröder