Código:
function search($array, $key, $value)
{
$results = array();
if (is_array($array)) {
if (isset($array[$key]) && $array[$key] == $value) {
$results[] = $array;
}
foreach ($array as $subarray) {
$results = array_merge($results, search($subarray, $key, $value));
}
}
return $results;
}
$arr = array(0 => array(id=>1,name=>"cat 1"),
1 => array(id=>2,name=>"cat 2"),
2 => array(id=>3,name=>"cat 1"));
print_r(search($arr, 'name', 'cat 1'));
Salida:
Array
(
[0] => Array
(
[id] => 1
[name] => cat 1
)
[1] => Array
(
[id] => 3
[name] => cat 1
)
)
Si la eficiencia es importante, puede escribirla para que todas las llamadas recursivas almacenen sus resultados en la misma $results
matriz temporal en lugar de fusionar las matrices juntas, de esta manera:
function search($array, $key, $value)
{
$results = array();
search_r($array, $key, $value, $results);
return $results;
}
function search_r($array, $key, $value, &$results)
{
if (!is_array($array)) {
return;
}
if (isset($array[$key]) && $array[$key] == $value) {
$results[] = $array;
}
foreach ($array as $subarray) {
search_r($subarray, $key, $value, $results);
}
}
La clave es que search_r
toma su cuarto parámetro por referencia en lugar de por valor; El comercial &
es crucial.
FYI: Si tiene una versión anterior de PHP, debe especificar la parte de paso por referencia en la llamada en search_r
lugar de en su declaración. Es decir, la última línea se convierte search_r($subarray, $key, $value, &$results)
.
$key
no existe en la matriz? ¿No sería mejor hacerloif (array_key_exists($key, $array) && $array[$key] == $value) {
?$value
que esnull
y la función no funciona ...array empty
... ¿Cómo tener una matriz incluso si$value
=null
? comosearch($array, 'id', null)
?¿Qué tal la versión SPL en su lugar? Te ahorrará algo de tipeo:
Lo bueno es que básicamente el mismo código iterará a través de un directorio para usted, utilizando un RecursiveDirectoryIterator en lugar de un RecursiveArrayIterator. SPL es el roxor.
Lo único malo de SPL es que está mal documentado en la web. Pero varios libros de PHP tienen algunos detalles útiles, particularmente Pro PHP; y probablemente también puedas buscar en Google más información.
fuente
Ref: http://php.net/manual/en/function.array-filter.php
fuente
Volví a publicar esta actualización para cualquiera que necesite un consejo de optimización en estas respuestas, particularmente la gran respuesta de John Kugelman arriba.
Su función publicada funciona bien, pero tuve que optimizar este escenario para manejar un conjunto de resultados de 12 000 filas. La función estaba tardando 8 segundos eternos en revisar todos los registros, muuuuuuuuuuucho mucho tiempo.
Simplemente necesitaba la función para DETENER la búsqueda y regresar cuando se encontró coincidencia. Es decir, si busca un customer_id, sabemos que solo tenemos uno en el conjunto de resultados y una vez que encontramos el customer_id en la matriz multidimensional, queremos volver.
Aquí está la versión de esta función con velocidad optimizada (y mucho más simplificada), para cualquier persona que lo necesite. A diferencia de otras versiones, solo puede manejar una sola profundidad de matriz, no se repite y elimina la fusión de múltiples resultados.
Esto redujo la tarea de hacer coincidir los 12 000 registros con 1,5 segundos. Sigue siendo muy costoso pero mucho más razonable.
fuente
Una mejora menor a la versión rápida.
fuente
Tenga cuidado con los algoritmos de búsqueda lineal (los anteriores son lineales) en matrices multidimensionales, ya que han agravado la complejidad ya que su profundidad aumenta el número de iteraciones necesarias para atravesar toda la matriz. P.ej:
tomaría como máximo 200 iteraciones para encontrar lo que está buscando (si la aguja estuviera en [100] [1]), con un algoritmo adecuado.
Los algoritmos lineales en este caso funcionan en O (n) (ordenar el número total de elementos en toda la matriz), esto es pobre, un millón de entradas (por ejemplo, una matriz de 1000x100x10) tomaría en promedio 500,000 iteraciones para encontrar la aguja. Además, ¿qué pasaría si decidiera cambiar la estructura de su matriz multidimensional? Y PHP lanzaría un algoritmo recursivo si su profundidad fuera más de 100. La informática puede mejorar:
Siempre que sea posible, use siempre objetos en lugar de matrices multidimensionales:
y aplique una interfaz y función de comparación personalizadas para ordenarlas y encontrarlas:
Puede
uasort()
utilizar un comparador personalizado; si se siente aventurero, debe implementar sus propias colecciones para sus objetos que puedan ordenarlos y administrarlos (siempre extiendo ArrayObject para incluir una función de búsqueda como mínimo).Una vez que se ordenan (uasort es O (n log n), que es tan bueno como se supera a los datos arbitrarios), la búsqueda binaria puede hacer la operación en tiempo O (log n), es decir, un millón de entradas solo requieren ~ 20 iteraciones para buscar. Que yo sepa, la búsqueda binaria de comparación personalizada no está implementada en PHP (
array_search()
usa un orden natural que funciona en referencias de objetos, no en sus propiedades), tendría que implementar esto usted mismo como lo hago yo.Este enfoque es más eficiente (ya no hay profundidad) y lo más importante es universal (suponiendo que imponga la comparabilidad usando interfaces) ya que los objetos definen cómo se ordenan, por lo que puede reciclar el código infinitamente. Mucho mejor =)
fuente
Aquí hay solución:
fuente
fuente
http://snipplr.com/view/51108/nested-array-search-by-value-or-key/
fuente
fuente
Necesitaba algo similar, pero para buscar una matriz multidimensional por valor ... Tomé el ejemplo de John y escribí
Espero que ayude a alguien :)
fuente
Esta es una función revisada de la que John K. publicó ... Necesito tomar solo la clave específica en la matriz y nada por encima.
fuente
Y otra versión que devuelve el valor clave del elemento de matriz en el que se encuentra el valor (sin recursividad, optimizado para la velocidad):
Gracias a todos los que publicaron aquí.
fuente
fuente
Si desea buscar un conjunto de claves, esto es bueno
Las claves no se sobrescribirán porque cada conjunto de valores clave => estará en una matriz separada en la matriz resultante.
Si no quieres claves duplicadas, usa esta
fuente