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'));
Resultado:
Array
(
[0] => Array
(
[id] => 1
[name] => cat 1
)
[1] => Array
(
[id] => 3
[name] => cat 1
)
)
Se a eficiência é importante, você pode escrevê-la para que todas as chamadas recursivas armazenem seus resultados na mesma $results
matriz temporária, em vez de mesclar matrizes, da seguinte forma:
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);
}
}
A chave é aquela que search_r
pega seu quarto parâmetro por referência e não por valor; oe comercial &
é crucial.
FYI: Se você tiver uma versão mais antiga do PHP, então você tem que especificar a parte passagem por referência na chamada para search_r
, em vez de na sua declaração. Ou seja, a última linha se torna search_r($subarray, $key, $value, &$results)
.
$key
ele não existir na matriz? Não seria melhor fazerif (array_key_exists($key, $array) && $array[$key] == $value) {
?$value
que énull
e a função não funciona ...array empty
... Como ter uma matriz mesmo se$value
=null
? gostasearch($array, 'id', null)
?Que tal a versão SPL ? Isso poupará algumas digitações:
O que é bom é que basicamente o mesmo código irá percorrer um diretório para você, usando um RecursiveDirectoryIterator em vez de um RecursiveArrayIterator. SPL é o roxor.
A única chatice sobre SPL é que ela está mal documentada na web. Mas vários livros sobre PHP abordam alguns detalhes úteis, principalmente o Pro PHP; e você provavelmente pode pesquisar no Google para obter mais informações também.
fonte
Ref: http://php.net/manual/en/function.array-filter.php
fonte
Voltei para publicar esta atualização para qualquer pessoa que precise de uma dica de otimização nessas respostas, especialmente a excelente resposta de John Kugelman acima.
Sua função postada funciona bem, mas tive que otimizar esse cenário para lidar com um conjunto de resultados de 12.000 linhas. A função estava demorando 8 segundos eternos para passar por todos os registros, tempo demais.
Eu simplesmente precisava da função para PARAR a busca e retornar quando a correspondência era encontrada. Ou seja, se estiver procurando por um customer_id, sabemos que só temos um no conjunto de resultados e, uma vez que encontramos o customer_id na matriz multidimensional, queremos retornar.
Aqui está a versão otimizada para velocidade (e muito simplificada) dessa função, para quem precisa. Diferente de outras versões, ele pode lidar apenas com uma profundidade de matriz, não recursa e acaba com a mesclagem de vários resultados.
Isso reduziu a tarefa de corresponder os 12.000 registros a 1,5 segundos. Ainda muito caro, mas muito mais razoável.
fonte
Uma pequena melhoria para a versão rápida.
fonte
Tenha cuidado com os algoritmos de pesquisa linear (os acima são lineares) em matrizes multidimensionais, pois elas aumentam a complexidade, pois sua profundidade aumenta o número de iterações necessárias para percorrer toda a matriz. Por exemplo:
seriam necessárias no máximo 200 iterações para encontrar o que você estava procurando (se a agulha estivesse em [100] [1]), com um algoritmo adequado.
Os algoritmos lineares, neste caso, são executados em O (n) (número total de elementos da ordem em todo o array); isso é ruim; um milhão de entradas (por exemplo, um array de 1000x100x10) levaria em média 500.000 iterações para encontrar a agulha. Além disso, o que aconteceria se você decidisse alterar a estrutura de sua matriz multidimensional? E o PHP lançaria um algoritmo recursivo se sua profundidade fosse superior a 100. A ciência da computação pode fazer melhor:
Sempre que possível, sempre use objetos em vez de várias matrizes dimensionais:
e aplique uma interface e função comparadora personalizada para classificá-las e localizá-las:
Você pode usar
uasort()
para utilizar um comparador personalizado; se estiver se aventurando, deve implementar suas próprias coleções para seus objetos que podem classificá-los e gerenciá-los (eu sempre estendo o ArrayObject para incluir no mínimo uma função de pesquisa).Depois de ordenadas (uasort é O (n log n), o que é tão bom quanto obtém dados arbitrários), a pesquisa binária pode fazer a operação em O (log n), ou seja, um milhão de entradas leva apenas 20 iterações para procurar. Tanto quanto sei, a pesquisa binária do comparador personalizado não está implementada no PHP (
array_search()
usa ordenação natural que funciona em referências a objetos e não em suas propriedades), você teria que implementar isso como você.Essa abordagem é mais eficiente (não existe mais profundidade) e, mais importante, universal (supondo que você imponha comparabilidade usando interfaces), pois os objetos definem como eles são classificados, para que você possa reciclar o código infinitamente. Muito melhor =)
fonte
Aqui está a solução:
fonte
fonte
http://snipplr.com/view/51108/nested-array-search-by-value-or-key/
fonte
fonte
Eu precisava de algo semelhante, mas para procurar matriz multidimensional por valor ... tomei o exemplo de John e escrevi
Espero que ajude alguém :)
fonte
Esta é uma função revisada daquela que John K. postou ... Eu preciso pegar apenas a chave específica na matriz e nada acima dela.
fonte
E outra versão que retorna o valor da chave do elemento da matriz em que o valor é encontrado (sem recursão, otimizado para velocidade):
Obrigado a todos que postaram aqui.
fonte
fonte
Se você deseja procurar por uma série de chaves, isso é bom
As chaves não serão substituídas porque cada conjunto de chave => valores estará em uma matriz separada na matriz resultante.
Se você não quiser chaves duplicadas, use esta
fonte