php - pobierz numeryczny indeks tablicy asocjacyjnej

154

Mam tablicę asocjacyjną i muszę znaleźć numeryczną pozycję klucza. Mógłbym ręcznie przejrzeć tablicę, aby ją znaleźć, ale czy istnieje lepszy sposób wbudowania w PHP?

$a = array(
  'blue'   => 'nice',
  'car'    => 'fast',
  'number' => 'none'
);

// echo (find numeric index of $a['car']); // output: 1
n00b
źródło

Odpowiedzi:

273
echo array_search("car",array_keys($a));
Fosco
źródło
5
Czy PHP gwarantuje porządek tablicy asocjacyjnej?
Kevin Burke
7
@KevinBurke Nie zmieni kolejności, chyba że użyjesz funkcji sortowania. Nie jestem pewien, jakiego rodzaju gwarancji szukasz, ale nie przypomina modelu JavaScript, w którym nie ma statycznej kolejności tablic asocjacyjnych.
Fosco
6
Indeksy podane przez „array_keys” niekoniecznie będą zgodne z indeksem oryginalnej tablicy. Na przykład, jeśli zmienisz tablicę za pomocą „unset” lub kilku innych funkcji, w indeksie oryginalnej tablicy pozostanie luka, ale array_keys utworzy nową tablicę.
SEoF
4
To NIE array("val1", "val2", "car" => "val3")0
DZIAŁA,
Czym to się różni od odpowiedzi @ quantamSoup?
Mistyczne
35
$blue_keys = array_search("blue", array_keys($a));

http://php.net/manual/en/function.array-keys.php

quantumSoup
źródło
8
+1 uratowało mi 5 chwil szukania przez Google tej funkcji, której użyłem do wpisania tego komentarza.
Aditya MP,
2

  $a = array(
      'blue' => 'nice',
      'car' => 'fast',
      'number' => 'none'
  );  
var_dump(array_search('car', array_keys($a)));
var_dump(array_search('blue', array_keys($a)));
var_dump(array_search('number', array_keys($a)));

Asterión
źródło
2
function arrayValuePosition($value, $array)
{
    return array_search($value, array_keys($array));
}
Andrey Vorobyev
źródło
2

Chociaż odpowiedź Fosco nie jest błędna, należy rozważyć przypadek z tym: tablice mieszane. Wyobraź sobie, że mam taką tablicę:

$a = array(
  "nice",
  "car" => "fast",
  "none"
);

Otóż, PHP pozwala na taką składnię, ale ma jeden problem: jeśli uruchamiam kod Fosco, otrzymuję 0 nieprawidłowy dla mnie kod , ale dlaczego tak się dzieje?
Ponieważ podczas porównywania ciągów znaków i liczb całkowitych PHP konwertuje ciągi znaków na liczby całkowite (i moim zdaniem jest to trochę głupie), więc podczas array_search()wyszukiwania indeksu zatrzymuje się na pierwszym, ponieważ najwyraźniej ("car" == 0) jest prawdziwy .
Ustawienie array_search()trybu ścisłego nie rozwiąże problemu, ponieważ wtedy array_search("0", array_keys($a))zwróci wartość false, nawet jeśli istnieje element o indeksie 0.
Więc moje rozwiązanie po prostu konwertuje wszystkie indeksy z array_keys()na ciągi, a następnie porównuje je poprawnie:

echo array_search("car", array_map("strval", array_keys($a)));

Wydruki 1, co jest poprawne.

EDYCJA:
Jak zauważył Shaun w poniższym komentarzu, to samo dotyczy wartości indeksu, jeśli zdarzy się, że szukasz indeksu int w następujący sposób:

$a = array(
  "foo" => "bar",
  "nice",
  "car" => "fast",
  "none"
);
$ind = 0;
echo array_search($ind, array_map("strval", array_keys($a)));

Zawsze otrzymasz 0, co jest błędne, więc rozwiązaniem byłoby rzutowanie indeksu (jeśli używasz zmiennej) na ciąg podobny do tego:

$ind = 0;
echo array_search((string)$ind, array_map("strval", array_keys($a)));
Xriuk
źródło
1
Przekazując zmienną, należy również rzutować ją jako ciąg, ponieważ przekazanie zera do tablicy asocjacyjnej miałoby ten sam negatywny skutek. Na przykład: var_dump(array_search(0, array_map("strval", array_keys($a))));zawsze wyświetli int (0)zamiast bool (false).
Shaun Cockerill
@ShaunCockerill right! Zaktualizowałem moją odpowiedź, dzięki za wskazanie tego!
Xriuk
0

rozwiązanie, które wymyśliłem ... prawdopodobnie mało wydajne w porównaniu z rozwiązaniem Fosco:

 protected function getFirstPosition(array$array, $content, $key = true) {

  $index = 0;
  if ($key) {
   foreach ($array as $key => $value) {
    if ($key == $content) {
     return $index;
    }
    $index++;
   }
  } else {
   foreach ($array as $key => $value) {
    if ($value == $content) {
     return $index;
    }
    $index++;
   }
  }
 }
n00b
źródło
2
Tak, PHP ma tysiące wbudowanych funkcji nie bez powodu. Są one zwykle znacznie szybsze niż równoważna logika zapisana w kodzie PHP.
Bill Karwin
3
Jest to prawdopodobnie szybsze niż array_search, które wykonuje najpierw sortowanie, więc boleśnie powolne.
Alasdair
Ach, ale wbudowany kod jest prekompilowany, a wyszukiwanie najprawdopodobniej będzie wyszukiwaniem binarnym (zakładając, że najpierw posortuje elementy).
SEoF
0

Wszystkie rozwiązania oparte na array_keys nie działają dla tablic mieszanych. Rozwiązanie jest proste:

echo array_search($needle,array_keys($haystack), true);

Z php.net: Jeśli trzeci parametr ścisły jest ustawiony na TRUE, funkcja array_search () wyszuka identyczne elementy w stogu siana. Oznacza to, że przeprowadzi również ścisłe porównanie typu igły w stogu siana, a obiekty muszą być w tej samej instancji.

MrBlc
źródło