Comment faire une recherche par clé=>valeur dans un tableau multidimensionnel en PHP
Est-il un moyen rapide pour obtenir tous les sous-tableaux où une valeur clé de la paire a été trouvé dans un tableau multidimensionnel? Je ne peux pas dire à quelle profondeur le tableau sera.
Simple exemple de tableau:
$arr = array(0 => array(id=>1,name=>"cat 1"),
1 => array(id=>2,name=>"cat 2"),
2 => array(id=>3,name=>"cat 1")
);
Lorsque je recherche de la clé=nom et la valeur="cat 1" la fonction doit retourner:
array(0 => array(id=>1,name=>"cat 1"),
1 => array(id=>3,name=>"cat 1")
);
Je suppose que la fonction récursive pour descendre au niveau le plus profond.
Vous devez vous connecter pour publier un commentaire.
Code:
De sortie:
Si l'efficacité est importante, vous pourriez écrire si tous les appels récursifs de stocker leurs résultats dans la même temporaire
$results
tableau plutôt que la fusion de tableaux, comme suit:La clé il n'y a que
search_r
prend sa quatrième paramètre par référence plutôt que par valeur; l'esperluette&
est crucial.Pour info: Si vous avez une ancienne version de PHP, vous devez spécifier le passage par référence en partie dans le appel à
search_r
plutôt que dans sa déclaration. Qui est, la dernière ligne devientsearch_r($subarray, $key, $value, &$results)
.$key
n'existe pas dans le tableau? Wouldnt être mieux à faireif (array_key_exists($key, $array) && $array[$key] == $value) {
?$value
qui estnull
et la fonction ne fonctionne pas ...array empty
... Comment faire pour avoir un tableau, même si$value
=null
? commesearch($array, 'id', null)
?Comment au sujet de la SPL version à la place? Il vous permettra de gagner un peu de temps:
Ce qui est génial, c'est que, fondamentalement, le même code de parcourir un répertoire pour vous, à l'aide d'un RecursiveDirectoryIterator au lieu d'un RecursiveArrayIterator. SPL est le roxor.
La seule déception à propos de la SPL est qu'il est mal documenté sur le web. Mais plusieurs PHP livres d'entrer dans quelques détails utiles, en particulier Pro PHP; et vous pouvez probablement google pour plus d'info, trop.
Ref: http://php.net/manual/en/function.array-filter.php
Revint à publier cette mise à jour pour toute personne ayant besoin d'une optimisation de la pointe sur ces réponses, en particulier à Jean Kugelman de la grande réponse ci-dessus.
Son posté fonction du bon travail, mais j'ai eu à optimiser ce scénario pour la manipulation de 12 000 ligne du jeu de résultats. La fonction était de prendre un éternel 8 secondes pour passer à travers tous les registres, waaaaaay trop longtemps.
J'ai tout simplement besoin de la fonction pour ARRÊTER la recherche et de retour lorsque le match a été trouvé. C'est à dire, si vous cherchez un customer_id, nous savons que nous n'avons qu'un seul dans le jeu de résultats et une fois que nous trouvons dans le customer_id
le tableau multidimensionnel, nous voulons revenir.
Ici est la vitesse optimisée ( et beaucoup simplifié ) version de cette fonction, pour toute personne dans le besoin. Contrairement à d'autres version, il ne peut gérer qu'une seule profondeur de tableau, n'est pas récursif et fait disparaître la fusion de plusieurs résultats.
Ramené le la tâche de façon à correspondre à la 12 000 dossiers de 1,5 secondes. Encore très coûteuse mais beaucoup plus raisonnable.
Un mineur imporvement pour la version rapide.
Attention linéaire des algorithmes de recherche (ci-dessus sont linéaires) dans de multiples dimensions des tableaux qu'ils ont aggravé la complexité, sa profondeur augmente le nombre d'itérations nécessaires pour parcourir l'ensemble du tableau. Par exemple:
à plus de 200 itérations pour trouver ce que vous cherchez (si l'aiguille ont été à [100][1]), avec un algorithme convenable.
Linéaire des algorithmes dans ce cas, exécuter en O(n) (bon de commande nombre total d'éléments dans le tableau), ce qui est faible, un million d'entrées (par exemple, un 1000x100x10 tableau) prendrait en moyenne de 500 000 itérations pour trouver l'aiguille. Aussi ce qui se passerait si vous avez décidé de changer la structure de votre tableau multidimensionnel? Et PHP le coup de sortir un algorithme récursif si votre profondeur de plus de 100. L'informatique peut faire mieux:
Si possible, toujours utiliser des objets au lieu de plusieurs dimensions des tableaux:
et d'appliquer une coutume de comparaison de l'interface et de la fonction pour trier et de les trouver:
Vous pouvez utiliser
uasort()
d'utiliser une coutume de comparaison, si vous vous sentez aventureux, vous devriez mettre en œuvre vos propres collections pour vos objets qui permet de trier et de les gérer (j'ai toujours étendre ArrayObject pour inclure une fonction de recherche à tout le moins).Une fois qu'ils sont triés (uasort est O(n log n), ce qui est aussi bon qu'il obtient plus de données arbitraires), binaire de recherche peuvent faire l'opération en O(log n) le temps, c'est à dire un million d'entrées ne prend ~20 itérations de recherche. Pour autant que je suis conscient personnalisé comparateur binaire de recherche n'est pas implémenté en PHP (
array_search()
utilise l'ordre naturel qui fonctionne sur des références d'objet non leurs propriétés), pour la mise en œuvre de ce votre auto comme je le fais.Cette approche est plus efficace (il n'y a plus de profondeur) et, plus important universelle (en supposant que vous respecter la comparabilité de l'utilisation d'interfaces), car les objets de définir la façon dont ils sont triés, de sorte que vous pouvez recycler le code de l'infini. Beaucoup mieux =)
http://snipplr.com/view/51108/nested-array-search-by-value-or-key/
Voici la solution:
J'ai besoin de quelque chose de similaire, mais à la recherche de tableau multidimensionnel en valeur... j'ai pris exemple John et écrit
J'espère que cela aide quelqu'un 🙂
C'est une fonction révisée de celle que John K. posté... j'ai besoin de récupérer uniquement la clé spécifique dans le tableau et rien au-dessus d'elle.
Et une autre version qui retourne la valeur de la clé de l'élément du tableau dont la valeur est trouvée (pas de récursivité, optimisé pour la vitesse):
Merci à tous qui a posté ici.