php - получить числовой индекс ассоциативного массива

154

У меня есть ассоциативный массив, и мне нужно найти цифровую позицию ключа. Я мог бы перебрать массив вручную, чтобы найти его, но есть ли лучший способ встроить в PHP?

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

// echo (find numeric index of $a['car']); // output: 1
n00b
источник

Ответы:

273
echo array_search("car",array_keys($a));
Fosco
источник
5
Гарантирует ли PHP порядок ассоциативного массива?
Кевин Берк
7
@KevinBurke Это не будет переупорядочивать это, если вы не используете функцию сортировки. Не уверен, какую гарантию вы ищете, но это не похоже на модель JavaScript, где нет статического порядка для ассоциативных массивов.
Фоско
6
Индексы, заданные «array_keys», не обязательно будут совпадать с индексом исходного массива. Например, если вы изменили массив с помощью «unset» или ряда других функций, в индексе исходного массива останется пробел, но array_keys создаст новый массив.
СЕЕ
4
Это НЕ работает, если ассоциативный массив смешан, потому что array("val1", "val2", "car" => "val3")он будет производить 0, что неправильно ...
Xriuk
Чем это отличается от ответа @ quantamSoup?
Мистический
35
$blue_keys = array_search("blue", array_keys($a));

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

quantumSoup
источник
8
+1 спас мне 5 минут поиска в Google той функции, которую я использовал, чтобы напечатать этот комментарий.
Адитья депутат
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)));

АСТЕРИОН
источник
2
function arrayValuePosition($value, $array)
{
    return array_search($value, array_keys($array));
}
Андрей Воробьев
источник
2

Хотя ответ Fosco не является неправильным, есть случай, который нужно рассмотреть с этим: смешанные массивы. Представьте, что у меня есть такой массив:

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

Теперь PHP допускает такой синтаксис, но у него есть одна проблема: если я запускаю код Fosco, я получаю 0 неправильный код , но почему это происходит?
Потому что при выполнении сравнения между строками и целыми числами PHP преобразует строки в целые числа (и это, на мой взгляд, довольно глупо), поэтому при array_search()поиске индекса он останавливается на первом, потому что, по-видимому, ("car" == 0) это правда .
Установка array_search()в строгий режим не решит проблему, потому что тогда array_search("0", array_keys($a))вернет false, даже если элемент с индексом 0 существует.
Таким образом, мое решение просто конвертирует все индексы из array_keys()в строки и затем сравнивает их правильно:

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

Печатает 1, что правильно.

РЕДАКТИРОВАТЬ:
Как Shaun указал в комментарии ниже, то же самое относится и к значению индекса, если вам случится искать int индекс, как это:

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

Вы всегда получите 0, что неверно, поэтому решением будет привести индекс (если вы используете переменную) к строке, подобной этой:

$ind = 0;
echo array_search((string)$ind, array_map("strval", array_keys($a)));
Xriuk
источник
1
При передаче переменной вы также должны приводить ее как строку, так как передача нуля в ассоциативный массив будет иметь такой же отрицательный эффект. Например: var_dump(array_search(0, array_map("strval", array_keys($a))));всегда будет выводить int (0), а не bool (false).
Шон Кокерилл
@ShaunCockerill верно! Обновил мой ответ, спасибо за указание на это!
Xriuk
0

решение, которое я придумал ... вероятно, довольно неэффективно по сравнению с решением 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
источник
2
Да, в PHP есть тысячи встроенных функций по определенной причине. Они обычно намного быстрее, чем эквивалентная логика, написанная в PHP-коде.
Билл Карвин
3
Это, вероятно, быстрее, чем array_search, что делает сортировку в первую очередь, и поэтому мучительно медленно.
Alasdair
Ах, но встроенный код предварительно скомпилирован, и поиск, скорее всего, будет бинарным (при условии, что сначала выполняется сортировка элементов).
SEFF
0

Все решения на основе array_keys не работают для смешанных массивов. Решение простое:

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

Из php.net: Если третий параметр strict установлен в TRUE, функция array_search () будет искать идентичные элементы в стоге сена. Это означает, что он также выполнит строгое сравнение типов иголки в стоге сена, и объекты должны быть одного экземпляра.

MrBlc
источник