php - obtiene el índice numérico de la matriz asociativa

154

Tengo una matriz asociativa y necesito encontrar la posición numérica de una clave. Podría recorrer la matriz manualmente para encontrarla, pero ¿hay una mejor manera de construir en PHP?

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

// echo (find numeric index of $a['car']); // output: 1
n00b
fuente

Respuestas:

273
echo array_search("car",array_keys($a));
Fosco
fuente
55
¿PHP garantiza el orden de una matriz asociativa?
Kevin Burke
77
@KevinBurke No lo va a reordenar a menos que use una función de clasificación. No estoy seguro de qué tipo de garantía está buscando, pero no es como el modelo de JavaScript donde no hay un orden estático para las matrices asociativas.
Fosco
66
Los índices dados por "array_keys" no coincidirán necesariamente con el índice de la matriz original. Por ejemplo, si ha alterado la matriz utilizando "unset" o una serie de otras funciones, quedará un espacio en el índice de la matriz original, pero array_keys producirá una nueva matriz.
SEOF
44
Esto NO funciona si la matriz asociativa se mezcla, array("val1", "val2", "car" => "val3")ya que producirá 0, lo que está mal ...
Xriuk
¿En qué se diferencia esto de la respuesta
Místico
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
fuente
2
function arrayValuePosition($value, $array)
{
    return array_search($value, array_keys($array));
}
Andrey Vorobyev
fuente
2

Si bien la respuesta de Fosco no es incorrecta, hay un caso a considerar con esta: matrices mixtas. Imagina que tengo una matriz como esta:

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

Ahora, PHP permite este tipo de sintaxis, pero tiene un problema: si ejecuto el código de Fosco obtengo lo 0 que me parece incorrecto , pero ¿por qué sucede esto?
Porque cuando se hacen comparaciones entre cadenas y enteros, PHP convierte las cadenas en enteros (y esto es un poco estúpido en mi opinión), entonces cuando array_search()busca el índice se detiene en el primero porque aparentemente ("car" == 0) es cierto .
Establecer el array_search()modo estricto no resolverá el problema porque luego array_search("0", array_keys($a))devolvería falso incluso si existe un elemento con índice 0.
Entonces, mi solución solo convierte todos los índices de array_keys()a cadenas y luego los compara correctamente:

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

Impresiones 1, lo cual es correcto.

EDITAR:
Como Shaun señaló en el comentario a continuación, lo mismo se aplica al valor del índice, si busca un índice int como este:

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

Siempre obtendrá 0, lo cual es incorrecto, por lo que la solución sería convertir el índice (si usa una variable) en una cadena como esta:

$ind = 0;
echo array_search((string)$ind, array_map("strval", array_keys($a)));
Xriuk
fuente
1
Al pasar una variable, también debe convertirla como una cadena, ya que pasar cero a una matriz asociativa tendría el mismo efecto negativo. Por ejemplo: var_dump(array_search(0, array_map("strval", array_keys($a))));siempre saldrá int (0), en lugar de bool (false).
Shaun Cockerill
@ShaunCockerill correcto! Actualicé mi respuesta, ¡gracias por señalar esto!
Xriuk
0

una solución que se me ocurrió ... probablemente bastante ineficiente en comparación con la solución de 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
fuente
2
Sí, PHP tiene miles de funciones integradas por una razón. Estos suelen ser mucho más rápidos que la lógica equivalente escrita a lo largo del código PHP.
Bill Karwin
3
Esto es probablemente más rápido que array_search, lo que hace una especie primero y, por lo tanto, es muy lento.
Alasdair
Ah, pero el código incorporado está precompilado, y la búsqueda probablemente será una búsqueda binaria (suponiendo que primero clasifique los elementos).
SEF
0

Todas las soluciones basadas en array_keys no funcionan para matrices mixtas. La solución es simple:

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

Desde php.net: si el tercer parámetro estricto se establece en TRUE, la función array_search () buscará elementos idénticos en el pajar. Esto significa que también realizará una comparación de tipo estricta de la aguja en el pajar, y los objetos deben ser la misma instancia.

MrBlc
fuente