¿Cómo verificar si existe un valor específico en una clave específica en cualquier subarreglo de un arreglo multidimensional?

6 minutos de lectura

Avatar de usuario de Rob
Robar

Necesito buscar en una matriz multidimensional un valor específico en cualquiera de los subarreglos indexados.

En otras palabras, necesito verificar una sola columna de la matriz multidimensional para obtener un valor. Si el valor existe en cualquier parte de la matriz multidimensional, me gustaría devolver true de lo contrario false

$my_array = array(    
    0 =>  array(  
        "name"   => "john",  
        "id"    =>  4  
    ),  
    1   =>  array(  
        "name" =>  "mark",  
        "id" => 152  
    ), 
    2   =>  array(  
        "name" =>  "Eduard",  
        "id" => 152  
    )
);

Me gustaría saber la forma más rápida y eficiente de verificar si la matriz $my_array contiene un valor con la clave “id”. Por ejemplo, si id => 152 en cualquier lugar de la matriz multidimensional, me gustaría true.

  • Cómo obtener los números clave de los ids de los fondos. por ejemplo, el resultado será el 1,2 si buscamos id = 152. @mickmackusa, @Rob

    – manas paul

    20 de septiembre a las 7:58


  • Hola @mickmackusa, ¿puedes hacerlo por mí en la matriz anterior? También es el array_filter() es más rápido de buscar que el foreach? Porque tengo una matriz más grande para buscar con la misma clave.

    – manas paul

    20 de septiembre a las 10:15

  • @manas supongo que quieres este Elimine todos los demás comentarios con los que ha ensuciado la página. Si desea varios valores, simplemente no devuelva ni rompa stackoverflow.com/a/16439674/2943403

    – mickmackusa

    20 de septiembre a las 13:13

Nada será más rápido que un simple bucle. Puede mezclar y combinar algunas funciones de matriz para hacerlo, pero también se implementarán como un bucle.

function whatever($array, $key, $val) {
    foreach ($array as $item)
        if (isset($item[$key]) && $item[$key] == $val)
            return true;
    return false;
}

  • Cómo obtener los números clave de los ids de los fondos. por ejemplo, el resultado será el 1,2 si buscamos id = 152. @Dan Grossman

    – manas paul

    20 de septiembre a las 8:00

Avatar de usuario de Jazzer
jazzista

La forma más sencilla es esta:

$my_array = array(    
    0 =>  array(  
        "name"   => "john",  
        "id"    =>  4  
    ),  
    1   =>  array(  
        "name" =>  "mark",  
        "id" => 152  
    ), 
    2   =>  array(  
        "name" =>  "Eduard",  
        "id" => 152  
    )
);

if (array_search(152, array_column($my_array, 'id')) !== FALSE) {
  echo 'FOUND!';
} else {
  echo 'NOT FOUND!';
}

  • ¿Cómo obtener los valores clave (1 y 2) del valor de id (152) buscado?

    – manas paul

    19 sep a las 16:31


Avatar de usuario de Manuel Pardo
manuel pardo

**PHP >= 5.5

simplemente puedes usar esto

$key = array_search(40489, array_column($userdb, 'uid'));

Supongamos esta matriz multidimensional:

$userdb=Array
(
(0) => Array
    (
        (uid) => '100',
        (name) => 'Sandra Shush',
        (url) => 'urlof100'
    ),

(1) => Array
    (
        (uid) => '5465',
        (name) => 'Stefanie Mcmohn',
        (pic_square) => 'urlof100'
    ),

(2) => Array
    (
        (uid) => '40489',
        (name) => 'Michael',
        (pic_square) => 'urlof40489'
    )
);

$key = array_search(40489, array_column($userdb, 'uid'));

  • ¿Por qué no simplemente $ids = array_column($array, 'id', 'id'); y entonces isset($ids[40489])?

    – Elías Van Ootegem

    11 de agosto de 2016 a las 15:33

  • Oye, ¿te importaría actualizar tu respuesta e implementar el comentario de Elias?

    – Leymannx

    16 de febrero de 2017 a las 9:12

  • Es importante aclarar para futuros investigadores que $key quizás 0 que es un valor falso. Saber si array_search() encontrado datos de calificación, debe verificar explícitamente si $key !== false o $key === false dependiendo de sus necesidades.

    – mickmackusa

    18 de mayo de 2020 a las 10:26

Avatar de usuario de Friendly Code
Código amistoso

Aquí hay una versión actualizada de la respuesta de Dan Grossman que se adaptará a matrices multidimensionales (lo que buscaba):

function find_key_value($array, $key, $val)
{
    foreach ($array as $item)
    {
        if (is_array($item) && find_key_value($item, $key, $val)) return true;

        if (isset($item[$key]) && $item[$key] == $val) return true;
    }

    return false;
}

avatar de usuario de stewe
estofado

Si tiene que hacer muchas búsquedas de “id” y debería ser muy rápido, debe usar una segunda matriz que contenga todas las “id” como claves:

$lookup_array=array();

foreach($my_array as $arr){
    $lookup_array[$arr['id']]=1;
}

Ahora puede verificar una identificación existente muy rápido, por ejemplo:

echo (isset($lookup_array[152]))?'yes':'no';

Una buena solución puede ser proporcionada por @Elias Van Ootegan en un comentario que es:

$ids = array_column($array, 'id', 'id');
echo isset($ids[40489])?"Exist":"Not Exist";

Lo probé y funcionó para mí, gracias amigo.

editado

Nota: funcionará en PHP 5.5+

TMTOWTDI. Aquí hay varias soluciones en orden de complejidad.

(Sigue una breve introducción sobre la complejidad):O(n) o “gran o” significa el peor escenario de caso donde n significa el número de elementos en la matriz, y o(n) o “pequeña o” significa mejor de los casos. Larga historia de matemáticas discretas, tú realmente solo tiene que preocuparse por el peor de los casosy asegúrese de que no sea n ^ 2 o n!. Es más una medida de cambio en el tiempo de computación como n aumenta de lo que es el tiempo total de computación. Wikipedia tiene un buen artículo sobre la complejidad del tiempo computacional.

Si la experiencia me ha enseñado algo, es que pasar demasiado tiempo optimizando la pequeña o de sus programas es una clara pérdida de tiempo que es mejor emplear en hacer algo, cualquier cosa, mejor.

Solución 0: O(n) / o(1) complejidad:

Esta solución tiene el mejor de los casos de 1 comparación: 1 iteración a través del bucle, pero solo siempre que el valor coincidente esté en la posición 0 de la matriz. El peor de los casos es que no está en la matriz y, por lo tanto, tiene que iterar sobre cada elemento de la matriz.

foreach ($my_array as $sub_array) {
    if (@$sub_array['id'] === 152) {
        return true;
    }
}
return false;

Solución 1: O(n) / o(n) complejidad:

Esta solución debe recorrer toda la matriz sin importar dónde esté el valor coincidente, por lo que siempre será n iteraciones a través de la matriz.

return 0 < count(
    array_filter(
        $my_array,
        function ($a) {
            return array_key_exists('id', $a) && $a['id'] == 152;
        }
    )
);

Solución 2: O(n log n) / o(n log n) complejidad:

Una inserción hash es donde el log n viene de; n inserciones hash = n * log n. Hay una búsqueda hash al final que es otra log n pero no está incluido porque así es como funciona la matemática discreta.

$existence_hash = [];
foreach ($my_array as $sub_array) {
    $existence_hash[$sub_array['id']] = true;
}
return @$existence_hash['152'];

  • Fundición array_filter()valor devuelto como (bool) le ahorrará tener que contar los resultados o compararlos con 0. 3v4l.org/2dVAu Para cualquiera que esté buscando la técnica más eficiente (y el OP lo está), usando array_filter() continuará iterando la matriz de entrada incluso después de encontrar una coincidencia, por lo que esta no será la mejor manera.

    – mickmackusa

    18 de mayo de 2020 a las 7:50

  • los count() llamar es un O(1) operación, por lo que no hay optimización mediante el uso de una conversión. Incluso si lo escribes como un cortocircuito for bucle, el peor de los casos seguiría siendo O(n) ya que la identificación no podría existir en $my_array.

    – anfetamáquina

    18 mayo 2020 a las 17:57

  • al convertir a (bool) no hay llamada de función ni comparación condicional en array_filter()devuelve el valor por lo que es más directo y conciso convertir a tipo booleano. La técnica de DanGrossman (aunque usaría llaves para todas las construcciones del lenguaje) será la que mejor se desempeñe porque ejecuta un retorno/pausa anticipada condicional. Estoy seguro de que ya sabes esto; Solo estoy afirmando este hecho para los investigadores. Agregue una explicación a su respuesta para modelar mejores comportamientos de publicación para los usuarios más nuevos.

    – mickmackusa

    18 mayo 2020 a las 21:46

¿Ha sido útil esta solución?