Zdobądź pierwszy klucz w (ewentualnie) tablicy asocjacyjnej?


756

Jaki jest najlepszy sposób ustalenia pierwszego klucza w potencjalnie asocjacyjnej tablicy? Najpierw pomyślałem, że po prostu przewidziełem tablicę, a potem natychmiast ją złamałem, tak:

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

Zatem posiadanie klucza $ zawiera pierwszy klucz, ale wydaje się to nieefektywne. Czy ktoś ma lepsze rozwiązanie?


4
Dlaczego nieefektywne foreach?
— Emilio Gort

2
W porównaniu do wszystkich odpowiedzi, foreach jest nadal najszybszym FIDDLE, PHP 5.3 , mój test localhost na PHP 5.5 pokazuje, że różnica jest nieco na korzyść foreach.
— Danijel

3
@Danijel, foreachjest semantycznie błędny.
— Pacerier

2
@AlexS, albo each($arr)['key']albo each($arr)[0]będzie działać.
— Pacerier

1
@Danijel Już nie ... klucz 0.01070.0217
— :,

Odpowiedzi:


1337

Aktualizacja 2019

Począwszy od PHP 7.3 pojawiła się nowa wbudowana funkcja o nazwie, array_key_first()która pobierze pierwszy klucz z podanej tablicy bez resetowania wewnętrznego wskaźnika. Sprawdź dokumentację, aby uzyskać więcej informacji.


Możesz użyć reseti key:

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

Zasadniczo jest taki sam jak początkowy kod, ale ma nieco mniejszy narzut i bardziej oczywiste jest, co się dzieje.

Pamiętaj tylko, aby zadzwonić reset, w przeciwnym razie możesz dostać dowolny klucz z tablicy. Możesz także użyć endzamiast, resetaby uzyskać ostatni klucz.

Jeśli chcesz, aby klucz uzyskał pierwszą wartość, resetfaktycznie ją zwraca:

$first_value = reset($array);

Jest jednak jeden szczególny przypadek, na który należy uważać (więc najpierw sprawdź długość tablicy):

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

141
Na marginesie, reset()zdarza się również, że zwraca pierwszy element (wartość, a nie klucz) z dowolnej tablicy, co również może być przydatne.
— devios1

5
W dokumentacji jest komentarz do reset()powiedzenia Don't use reset () `, aby uzyskać pierwszą wartość tablicy asocjacyjnej. Działa świetnie dla prawdziwych tablic, ale działa nieoczekiwanie na obiektach Iterator. bugs.php.net/bug.php?id=38478 `Czy to nadal prawda? Jestem zdezorientowany
— Dmitrij Paszkiewicz

13
@DmitryPashkevich: Nie przejmuj się tym komentarzem. Nie mówią o arrayobiektach, ale o obiektach niestandardowych (które nie są rzeczywistymi tablicami). Sądzę, że pomylili różnice w strukturach danych, ale w zasadzie resetzwraca wartość pierwszego „klucza”, który dla obiektów byłby $propw przykładzie podanym w raporcie „błędu”, ale dla tablicy pierwszy klucz. Więc nie martw się, dopóki używasz prawdziwych tablic (utworzonych przy pomocy array(…)), nie będziesz mieć problemu.
— Blixt,

2
Należy wspomnieć, że end () i reset () mają efekt uboczny. Jednak większość kodu na świecie nie polega na tym, że wewnętrzny wskaźnik jest nigdzie, więc na ogół nie stanowi to problemu.
— donquixote

1
@ user3019105 Jest tylko jeden wewnętrzny wskaźnik tablicy na, co oznacza, że jeśli kod poza funkcją zmienia go (poprzez wywołanie next, reset, endlub pętli w tablicy), nie dostaniesz wartość oczekiwaną podczas rozmowy key. Tak, zawsze zadzwoń resetprzed użyciem, keyaby upewnić się, że dostaniesz to, czego chcesz.
— Blixt,

80

array_keyszwraca tablicę kluczy. Weź pierwszy wpis. Alternatywnie możesz wywołać resettablicę, a następnie key. To drugie podejście jest prawdopodobnie nieco szybsze (nie testowałem go), ale ma efekt uboczny resetowania wewnętrznego wskaźnika.


52
Tylko (późna) uwaga dla przyszłych czytelników: to drugie podejście jest nie tylko „nieco” szybsze. Istnieje duża różnica między iteracją całej tablicy, przechowywaniem każdego klucza w innej nowo utworzonej tablicy, a żądaniem pierwszego klucza tablicy jako łańcucha.
— Blixt,

3
Dlaczego nieefektywne foreach, jak operacja w pytaniu, porównuje do wszystkich tych odpowiedzi?
— Emilio Gort

5
@EmilioGort Dobre pytanie. Nie sądzę, żeby faktycznie istniała różnica w wydajności foreach+ breaki reset+ key. Ale ten pierwszy wygląda dość dziwnie, więc ze względów stylistycznych wolałbym ten drugi.
— troelskn

@EmilioGort: Afaik, foreach () kopiuje tablicę wewnętrznie. Możemy więc założyć, że jest wolniejszy. (Byłoby miło, gdyby ktoś mógł to potwierdzić)
— donquixote

3
@donquixote Nie wiem na pewno, ale zakładając, że jest to zwykła tablica (a nie obiekt implementujący jakiś interfejs lub interfejs Iteratora), jestem pewien, foreachże nie tworzy dla niej wewnętrznej kopii, a jedynie iteruje wskaźnik , podobnie jak przy użyciu więcej niskiego poziomu next, currentitd
— troelskn

54

Co ciekawe, pętla foreach jest w rzeczywistości najbardziej efektywnym sposobem na zrobienie tego.

Ponieważ PO konkretnie zapytał o efektywność, należy zauważyć, że wszystkie obecne odpowiedzi są w rzeczywistości znacznie mniej skuteczne niż foreach.

Zrobiłem test porównawczy na php 5.4, a metoda reset / wskaźnik klucza (zaakceptowana odpowiedź) wydaje się być około 7 razy wolniejsza niż foreach. Inne podejścia do manipulowania całą tablicą (array_keys, array_flip) są oczywiście jeszcze wolniejsze i stają się znacznie gorsze podczas pracy z dużą tablicą.

Foreach wcale nie jest nieefektywny, możesz go używać!

Edytuj 2015-03-03:

Zażądano skryptów testowych, nie mam oryginalnych, ale wykonałem kilka nowych testów. Tym razem znalazłem foreach tylko około dwa razy szybciej niż reset / klucz. Użyłem tablicy 100-klawiszowej i każdą metodę milion razy uruchomiłem, aby uzyskać zauważalną różnicę, oto kod prostego testu porównawczego:

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

Na moim php 5.5 ten wynik:

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 + klucz http://3v4l.org/b4DrN/perf#tabs
foreach http://3v4l.org/gRoGD/perf#tabs


3
Czy masz gdzieś wzorce. Podobnie jak w przypadku testowania itp. W każdym razie dziękuję za ich uruchomienie!
— grypa

Chciałbym zwrócić uwagę na fakt, że przez cały test użyto tej samej tablicy. Myślę, że fakt ten ma znaczący wpływ na podejście Foreach. Jak wspomniano w komentarzu @donquixote do niektórych odpowiedzi powyżej - foreach wewnętrznie kopiuje tablicę. Mogę sobie wyobrazić, że ta kopia jest ponownie używana podczas uruchamiania testu porównawczego, ponieważ unikanie kopiowania tablicy zwiększa wydajność tylko w tym teście.
— Jarda

2
@Jarda Począwszy od php7, foreachnigdy nie kopiuj tablicy, chyba że zmodyfikujesz ją bezpośrednio w pętli foreach. Na php5 struktura tablicy może być kopiowana w niektórych przypadkach (gdy jej przelicznik> 1) i masz rację, może to mieć znaczący wpływ. Na szczęście nie ma się czym martwić na php7, gdzie problem został rozwiązany. Oto świetna lektura zarówno o tym, jak działa foreach teraz, jak i o przeszłości.
— Webmut,

2
od php7.2 przy użyciu powyższego testu porównawczego, Foreach jest wciąż najszybszy
— billynoah

36

key($an_array) da ci pierwszy klucz

edit per Blixt: powinieneś zadzwonić reset($array);przed, key($an_array)aby zresetować wskaźnik do początku tablicy.


7
Pamiętaj, że wskaźnik tablicy może nie znajdować się na pierwszym elemencie, patrz moja odpowiedź.
— Blixt

Myślę, że ta odpowiedź pomoże mojej sprawie bez resetu, ponieważ najpierw upewniam się, że tablica ma tylko jeden element. Dzięki
— groovenectar,


22

W wersji 2018+

Począwszy od wersji PHP 7.3 istnieje array_key_first()funkcja, która osiąga dokładnie to:

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

Dokumentacja jest dostępna tutaj . 😉


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

2
To chyba nie jest najbardziej wydajne.
— Yada

3
@Yada, tak, ale może to być zauważalne w rzadkich przypadkach; w większości przypadków czytelność i łatwość konserwacji mają znacznie większe znaczenie; i wolę także rozwiązanie, które nie mutuje oryginalnych obiektów / tablic: np. reset ($ ar); $ klucz = klucz ($ ar); - nie zawsze jest dobrym pomysłem, wolałbym wybrać rozwiązanie MartyIX, które jest bardziej zwięzłe niż moje, np .: array_keys ($ ar) [0];
— Sergiy Sokolenko

20

Jeśli wydajność nie jest dla Ciebie tak ważna, możesz użyć array_keys($yourArray)[0]w PHP 5.4 (i wyższych).

Przykłady:

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

Przewaga nad rozwiązaniem:

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

jest to, że możesz przekazać array_keys($arr)[0]jako parametr funkcji (tj doSomething(array_keys($arr)[0], $otherParameter).).

HTH


3
Czy array_keys($arr)[0]składnia jest poprawna?
— trante

5
Jest w PHP 5.4. To się nazywa array dereferencing. Patrz na przykład: schlueters.de/blog/archives/…
— Martin Vseticka

@trante, obowiązuje we wszystkich językach pod słońcem, z wyjątkiem PHP <5.4.
— Pacerier

13

Proszę znaleźć następujące:

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

Przykład roboczy:


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()dawka nie zwraca pierwszego klucza tablicy assoc. maksymalny zwrot maksymalnej wartości listy lub elementów tablicy
— Hamidreza

5
Nie żądanie OP, ale bardzo przydatne w niektórych sytuacjach.
— d.raev

9

Może to być również rozwiązanie:

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

Przetestowałem to i działa.

Kodeks roboczy .


3
array_flip (): Może odwracać tylko wartości STRING i INTEGER!
— Mauro

5

Aby ulepszyć rozwiązanie Webmut , dodałem następujące rozwiązanie:

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

Dane wyjściowe dla mnie w PHP 7.1 to:

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 

Jeśli zrobię to dla tablicy o rozmiarze 10000, wyniki będą

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 

Upłynął limit czasu metody array_keys po 30 sekundach (przy zaledwie 1000 elementów czas pozostałej części był mniej więcej taki sam, ale metoda array_keys miała około 7,5 sekundy).


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

3

Najlepszy sposób, który dla mnie zadziałał, to

array_shift(array_keys($array))

array_keys pobiera tablicę kluczy z tablicy początkowej, a następnie array_shiftwycina z niej wartość pierwszego elementu. W tym celu potrzebujesz PHP 5.4+.


3

To jest łatwiejszy sposób, jaki kiedykolwiek znalazłem. Szybki i tylko dwie linie kodu :-D

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


0

Jednowarstwowy:

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

# echos 'key1'

0

Dzisiaj musiałem poszukać pierwszego klucza mojej tablicy zwróconego przez żądanie POST. (I zanotuj numer identyfikatora formularza itp.)

Znalazłem to: Zwraca pierwszy klucz tablicy asocjacyjnej w PHP

http://php.net/key

Zrobiłem to i działa.

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

Może będzie to eko 15 minut od innego faceta. CYA.


-2

Możesz grać ze swoją tablicą

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

Aby uzyskać pierwszy element tablicy, którego możesz użyć, currenta dla ostatniego elementu możesz użyćend

Edytować

Żeby nie otrzymywać więcej głosów za odpowiedź, możesz przekonwertować klucz na wartość, używając array_keysi wykorzystując, jak pokazano powyżej.


1
To są wartości, a nie klucze.
— Victor Schröder,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.