Erhalten Sie den ersten Schlüssel in einem (möglicherweise) assoziativen Array?

756

Wie kann der erste Schlüssel in einem möglicherweise assoziativen Array am besten ermittelt werden? Mein erster Gedanke war, nur das Array zu finden und es dann sofort so zu brechen:

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

Wenn also $ key den ersten Schlüssel enthält, scheint dies ineffizient zu sein. Hat jemand eine bessere Lösung?

Alex S.
quelle
4
Warum ist foreach ineffizient?
Emilio Gort
2
Im Vergleich zu allen Antworten ist foreach immer noch das schnellste FIDDLE, PHP 5.3 . Mein Localhost-Test auf PHP 5.5 zeigt, dass der Unterschied leicht zugunsten von foreach ist.
Danijel
3
@Danijel, foreachist semantisch falsch.
Pacerier
2
@AlexS, Entweder each($arr)['key']oder each($arr)[0]würde funktionieren.
Pacerier
1
@Danijel Nicht mehr ... key : 0.0107, foreach:0.0217
SeanJA

Antworten:

1337

Update 2019

Ab PHP 7.3 gibt es eine neue integrierte Funktion namens, array_key_first()die den ersten Schlüssel aus dem angegebenen Array abruft, ohne den internen Zeiger zurückzusetzen. Weitere Informationen finden Sie in der Dokumentation .


Sie können verwenden resetund key:

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

Es ist im Wesentlichen dasselbe wie Ihr ursprünglicher Code, jedoch mit etwas weniger Aufwand, und es ist offensichtlicher, was passiert.

Denken Sie daran, anzurufen reset, sonst erhalten Sie möglicherweise einen der Schlüssel im Array. Sie können auch endanstelle von verwenden reset, um den letzten Schlüssel abzurufen.

Wenn Sie möchten, dass der Schlüssel den ersten Wert erhält, wird er resettatsächlich zurückgegeben:

$first_value = reset($array);

Es gibt jedoch einen Sonderfall, auf den Sie achten sollten (überprüfen Sie also zuerst die Länge des Arrays):

$arr1 = array(false);
$arr2 = array();
var_dump(reset($arr1) === reset($arr2)); // bool(true)
Blixt
quelle
141
Als Randnotiz wird reset()auch das erste Element (Wert, nicht Schlüssel) eines Arrays zurückgegeben, was ebenfalls nützlich sein kann.
Devios1
5
Es gibt einen Kommentar in der Dokumentation zu reset()sagen Don't use Reset () `den ersten Wert eines assoziativen Arrays zu erhalten. Es funktioniert hervorragend für echte Arrays, funktioniert jedoch unerwartet bei Iterator-Objekten. bugs.php.net/bug.php?id=38478 `Stimmt das noch? Ich bin verwirrt
Dmitry Pashkevich
13
@DmitryPashkevich: Mach dir keine Sorgen über diesen Kommentar. Sie sprechen nicht über arrayObjekte, sondern über benutzerdefinierte Objekte (die keine tatsächlichen Arrays sind). Ich denke, sie haben den Unterschied in den Datenstrukturen verwirrt, geben aber im Grunde resetden Wert des ersten "Schlüssels" zurück, der für Objekte $propin dem im "Fehler" -Report angegebenen Beispiel angegeben wäre , für ein Array jedoch den ersten Schlüssel. Machen Sie sich also keine Sorgen, solange Sie echte Arrays verwenden (erstellt mit array(…)), werden Sie kein Problem haben.
Blixt
2
Es sollte erwähnt werden, dass end () und reset () einen Nebeneffekt haben. Der meiste Code auf der Welt ist jedoch nicht darauf angewiesen, dass sich der interne Zeiger irgendwo befindet, sodass dies im Allgemeinen kein Problem darstellt.
Donquijote
1
@ user3019105 Es gibt nur einen internen Zeiger pro Array, das heißt, wenn jeder Code außerhalb Ihrer Funktion ändert (durch den Aufruf next, reset, endoder durch das Array Looping), werden Sie nicht den erwarteten Wert erhalten , wenn Sie anrufen key. Rufen Sie also immer an, resetbevor Sie verwenden key, um sicherzustellen, dass Sie das bekommen, was Sie wollen.
Blixt
80

array_keysGibt ein Array von Schlüsseln zurück. Nehmen Sie den ersten Eintrag. Alternativ können Sie resetdas Array aufrufen und anschließend key. Der letztere Ansatz ist wahrscheinlich etwas schneller (obwohl ich ihn nicht getestet habe), hat aber den Nebeneffekt, dass der interne Zeiger zurückgesetzt wird.

troelskn
quelle
52
Nur eine (späte) Anmerkung für zukünftige Leser: Letzterer Ansatz ist nicht nur "etwas" schneller. Es gibt einen großen Unterschied zwischen dem Iterieren eines gesamten Arrays, dem Speichern jedes Schlüssels in einem anderen neu erstellten Array und dem Anfordern des ersten Schlüssels eines Arrays als Zeichenfolge.
Blixt
3
Warum ist foreach ineffizient, wie es die Operation in der Frage im Vergleich zu all diesen Antworten getan hat?
Emilio Gort
5
@EmilioGort Gute Frage. Ich glaube nicht, dass es einen Unterschied in der Leistung von foreach+ breakund reset+ gibt key. Aber das erstere sieht ziemlich seltsam aus, daher würde ich für stilistische Fragen das letztere vorziehen.
Troelskn
@EmilioGort: Afaik, foreach () kopiert das Array intern. Wir können also davon ausgehen, dass es langsamer ist. (Wäre schön, wenn jemand das bestätigen könnte)
Donquixote
3
@donquixote Ich weiß es nicht genau, aber wenn es sich um ein reguläres Array handelt (und nicht um ein Objekt, das eine Art oder eine Iterator-Schnittstelle implementiert), bin ich mir ziemlich sicher, foreachdass keine interne Kopie dafür erstellt wird, sondern nur ein Zeiger iteriert wird , ähnlich wie bei der Verwendung der niedrigeren Ebene next, currentetc.
troelskn
54

Interessanterweise ist die foreach-Schleife der effizienteste Weg, dies zu tun.

Da das OP speziell nach Effizienz gefragt hat, sollte darauf hingewiesen werden, dass alle aktuellen Antworten tatsächlich viel weniger effizient sind als ein Foreach.

Ich habe diesbezüglich einen Benchmark mit PHP 5.4 durchgeführt, und die Reset / Key Pointer-Methode (akzeptierte Antwort) scheint etwa siebenmal langsamer zu sein als eine foreach. Andere Ansätze zur Manipulation des gesamten Arrays (array_keys, array_flip) sind offensichtlich noch langsamer und werden bei der Arbeit mit einem großen Array viel schlimmer.

Foreach ist überhaupt nicht ineffizient, verwenden Sie es einfach!

Bearbeiten 03.03.2015:

Es wurden Benchmark-Skripte angefordert, ich habe nicht die ursprünglichen, sondern stattdessen einige neue Tests durchgeführt. Diesmal fand ich den foreach nur etwa doppelt so schnell wie reset / key. Ich habe ein Array mit 100 Schlüsseln verwendet und jede Methode millionenfach ausgeführt, um einen spürbaren Unterschied zu erzielen. Hier ist der Code des einfachen Benchmarks:

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

Auf meinem PHP 5.5 gibt dies aus:

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

Zurücksetzen + Schlüssel http://3v4l.org/b4DrN/perf#tabs
foreach http://3v4l.org/gRoGD/perf#tabs

Webmut
quelle
3
Haben Sie die Benchmarks irgendwo. Wie du getestet hast usw. Wie auch immer, danke, dass du sie ausgeführt hast!
Grippe
Ich möchte darauf hinweisen, dass während des gesamten Tests dasselbe Array verwendet wird. Ich denke, dass diese Tatsache den foreach-Ansatz erheblich beeinflusst. Wie @donquixote im Kommentar zu einer Antwort oben erwähnt hat - foreach kopiert das Array intern. Ich kann mir vorstellen, dass diese Kopie beim Ausführen des Benchmarks wiederverwendet wird, da das Vermeiden des Kopierens von Arrays die Leistung nur innerhalb dieses Tests verbessert.
Jarda
2
@Jarda Ab php7 wird foreachdas Array niemals kopiert, es sei denn, Sie ändern es direkt in der foreach-Schleife. Auf PHP5 könnte die Array-Struktur in einigen Fällen kopiert werden (wenn ihr Refcount> 1 ist) und Sie haben tatsächlich Recht, dass dies dort einen signifikanten Einfluss haben könnte. Glücklicherweise gibt es auf PHP7, wo dieses Problem behoben wurde, keinen Grund zur Sorge. Hier ist eine großartige Lektüre darüber, wie foreach jetzt unter der Haube funktioniert und wie es in der Vergangenheit funktioniert hat.
Webmut
2
ab php7.2 mit dem oben genannten Benchmark ist foreach immer noch am schnellsten
billynoah
36

key($an_array) wird Ihnen den ersten Schlüssel geben

per Blixt bearbeiten: Sie sollten reset($array);vorher aufrufen key($an_array), um den Zeiger auf den Anfang des Arrays zurückzusetzen.

Jimyi
quelle
7
Denken Sie daran, dass sich der Zeiger des Arrays möglicherweise nicht am ersten Element befindet, siehe meine Antwort.
Blixt
Ich denke, diese Antwort hilft meinem Fall ohne Zurücksetzen, da ich zuerst sicherstellen muss, dass das Array nur ein Element enthält. Danke
groovenectar
23

Du könntest es versuchen

array_keys($data)[0]
Stopper
quelle
22

Für 2018+

Ab PHP 7.3 gibt es eine array_key_first()Funktion, die genau dies erreicht:

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

Dokumentation finden Sie hier . 😉

ivanaugustobd
quelle
21
list($firstKey) = array_keys($yourArray);
Sergiy Sokolenko
quelle
2
Dies ist wahrscheinlich nicht die effizienteste.
Yada
3
@ Yada, ja, aber dies kann in seltenen Fällen auffallen; In den meisten Fällen sind Lesbarkeit und Wartbarkeit von viel größerer Bedeutung. und ich bevorzuge auch eine Lösung, die die ursprünglichen Objekte / Arrays nicht mutiert: zB reset ($ ar); $ key = key ($ ar); - ist nicht immer eine gute Idee, ich würde lieber die Lösung von MartyIX wählen, die prägnanter ist als meine, zB: array_keys ($ ar) [0];
Sergiy Sokolenko
20

Wenn Effizienz für Sie nicht so wichtig ist, können Sie sie array_keys($yourArray)[0]in PHP 5.4 (und höher) verwenden.

Beispiele:

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

Der Vorteil gegenüber der Lösung:

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

ist, dass Sie array_keys($arr)[0]als Funktionsparameter (dh doSomething(array_keys($arr)[0], $otherParameter)) übergeben können.

HTH

Martin Vseticka
quelle
3
Ist die array_keys($arr)[0]Syntax gültig?
Trante
5
Es ist in PHP 5.4. Es heißt array dereferencing. Siehe zum Beispiel: schlueters.de/blog/archives/…
Martin Vseticka
@trante, Es ist in jeder Sprache unter der Sonne gültig, außer PHP <5.4.
Pacerier
13

Bitte finden Sie Folgendes:

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

Arbeitsbeispiel:

Schüler
quelle
12
$myArray = array(
    2 => '3th element',
    4 => 'first element',
    1 => 'second element',
    3 => '4th element'
);
echo min(array_keys($myArray)); // return 1
Hamidreza
quelle
1
@jurgemaister gibt den max()ersten Schlüssel eines Assoc-Arrays nicht zurück. Maximaler Rückgabewert Maximalwert einer Liste oder eines Array-Elements
Hamidreza
5
Nicht die OP-Anfrage, aber in einigen Situationen sehr nützlich.
d.raev
9

Dies könnte auch eine Lösung sein:

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

Ich habe es getestet und es funktioniert.

Arbeitscode .

Schüler
quelle
3
array_flip (): Kann nur STRING- und INTEGER-Werte umdrehen!
Mauro
5

Um die Lösung von Webmut zu verbessern , habe ich die folgende Lösung hinzugefügt:

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

Die Ausgabe für mich auf PHP 7.1 ist:

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 

Wenn ich dies für ein Array der Größe 10000 mache, werden die Ergebnisse

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 

Die Methode array_keys hat eine Zeitüberschreitung von 30 Sekunden (mit nur 1000 Elementen war das Timing für den Rest ungefähr gleich, aber die Methode array_keys hatte ungefähr 7,5 Sekunden).

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

Der beste Weg, der für mich funktioniert hat, war

array_shift(array_keys($array))

array_keys Ruft ein Array von Schlüsseln aus dem anfänglichen Array ab und array_shiftschneidet dann den ersten Elementwert daraus. Dazu benötigen Sie PHP 5.4+.

Yuriy Petrovskiy
quelle
3

Dies ist der einfachere Weg, den ich jemals gefunden hatte. Schnell und nur zwei Codezeilen :-D

$keys = array_keys($array);
echo $array[$keys[0]];
Salvi Pascual
quelle
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ć
quelle
1
Das Einfügen einer Erklärung hilft wirklich dabei, die Qualität Ihres Beitrags zu verbessern. Denken Sie daran, dass Sie die Frage für Leser in Zukunft beantworten und diese Personen möglicherweise die Gründe für Ihren Code-Vorschlag nicht kennen
MichaelvE
0

Ein Einzeiler:

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

# echos 'key1'
Kohjah Breese
quelle
0

Heute musste ich nach dem ersten Schlüssel meines Arrays suchen, der von einer POST-Anfrage zurückgegeben wurde. (Und notieren Sie sich die Nummer für eine Formular-ID usw.)

Nun, ich habe Folgendes gefunden: Gibt den ersten Schlüssel des assoziativen Arrays in PHP zurück

http://php.net/key

Ich habe das getan und es funktioniert.

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

Vielleicht wird es 15 Minuten von einem anderen Kerl öko. CYA.

Roupioz Clement
quelle
-2

Sie können mit Ihrem Array spielen

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

Um das erste Element des Arrays zu erhalten, können Sie es verwenden, currentund für das letzte Element können Sie es verwendenend

Bearbeiten

Nur um keine weiteren Stimmen für die Antwort zu erhalten, können Sie Ihren Schlüssel array_keyswie oben gezeigt in Wert umwandeln und verwenden.

Priyank
quelle
1
Dies sind Werte, keine Schlüssel.
Victor Schröder