¿Cómo comprobar si la matriz PHP es asociativa o secuencial?
PHP trata todas las matrices como asociativas, por lo que no hay funciones integradas. ¿ Alguien puede recomendar una forma bastante eficaz de comprobar si una matriz "es una lista" (contiene sólo claves numéricas a partir de 0)?
Básicamente, quiero poder diferenciar entre esto:
$sequentialArray = [
'apple', 'orange', 'tomato', 'carrot'
];
y esto:
$assocArray = [
'fruit1' => 'apple',
'fruit2' => 'orange',
'veg1' => 'tomato',
'veg2' => 'carrot'
];
Desde 8.1 PHP tiene una respuesta simple, array_is_list() .
Para el código heredado, puede utilizar la siguiente función (envolviéndola function_exists()
para que sea portátil):
if (!function_exists('array_is_list')) {
function array_is_list(array $arr)
{
if ($arr === []) {
return true;
}
return array_keys($arr) === range(0, count($arr) - 1);
}
}
Y luego puedes usar esta función con cualquier versión de PHP.
var_dump(array_is_list([])); // true
var_dump(array_is_list(['a', 'b', 'c'])); // true
var_dump(array_is_list(["0" => 'a', "1" => 'b', "2" => 'c'])); // true
var_dump(array_is_list(["1" => 'a', "0" => 'b', "2" => 'c'])); // false
var_dump(array_is_list(["a" => 'a', "b" => 'b', "c" => 'c'])); // false
Para simplemente verificar si la matriz tiene claves que no sean enteras (no si la matriz está indexada secuencialmente o indexada a cero):
function has_string_keys(array $array) {
return count(array_filter(array_keys($array), 'is_string')) > 0;
}
Si hay al menos una clave de cadena, $array
se considerará una matriz asociativa.
Seguramente esta es una mejor alternativa.
<?php
$arr = array(1,2,3,4);
$isIndexed = array_values($arr) === $arr;
Muchos comentaristas de esta pregunta no entienden cómo funcionan las matrices en PHP. De la documentación de la matriz :
Una clave puede ser un número entero o una cadena. Si una clave es la representación estándar de un número entero, se interpretará como tal (es decir, "8" se interpretará como 8, mientras que "08" se interpretará como "08"). Los flotantes en la clave se truncan a un número entero. Los tipos de matriz indexada y asociativa son el mismo tipo en PHP, que pueden contener índices enteros y de cadena.
En otras palabras, no existe una clave de matriz de "8" porque siempre se convertirá (silenciosamente) al número entero 8. Por lo tanto, no es necesario tratar de diferenciar entre números enteros y cadenas numéricas.
Si desea la forma más eficiente de verificar una matriz en busca de claves no enteras sin hacer una copia de parte de la matriz (como lo hace array_keys()) o de toda ella (como lo hace foreach):
function keyedNext( &$arr, &$k){
$k = key($arr);
return next($arr);
}
for ($k = key(reset($my_array)); is_int($k); keyedNext($my_array,$k))
$onlyIntKeys = is_null($k);
Esto funciona porque key() devuelve NULL cuando la posición actual de la matriz no es válida y NULL nunca puede ser una clave válida (si intenta usar NULL como clave de matriz, se convierte silenciosamente a "").
PHP 8.1 agrega una función incorporada para determinar si una matriz es una lista con esa semántica o no. la función es array_is_list
:
$list = ["a", "b", "c"];
array_is_list($list); // true
$notAList = [1 => "a", 2 => "b", 3 => "c"];
array_is_list($notAList); // false
$alsoNotAList = ["a" => "a", "b" => "b", "c" => "c"];
array_is_list($alsoNotAList); // false
Tenga en cuenta que esta función regresa true
en matrices vacías.
array_is_list([]); // true
referencia