Le problème que vous rencontrez implique une récursion et/ou une traversée d'arbre. PHP supporte la traversée d'arbre d'un tableau avec les RecursiveArrayIterator
et RecursiveIteratorIterator
.
Pour obtenir toutes les clés de tous les tableaux parents, vous devez aller du premier niveau à la profondeur actuelle et récupérer les clés. Ceci est également supporté par RecursiveIteratorIterator
avec la méthode getSubIterator()
. Ce n'est pas vraiment bien documenté dans le manuel, alors voici un exemple:
$it = new RecursiveIteratorIterator(
new RecursiveArrayIterator($array)
);
foreach ($it as $value) {
if ($value !== 'x') continue;
$keys = array();
$depth = $it->getDepth();
for ($i = 0; $keys[] = $it->getSubIterator($i)->key(), $depth--; $i++);
echo implode(', ', $keys), ', ', $value, "\n";
}
Dans cet exemple, tout d'abord la RecursiveArrayIterator
avec votre $array
est créé. Pour activer la traversée de l'arbre, il est enveloppé dans le RecursiveIteratorIterator
. Ceci est nécessaire pour utiliser l'$it
-iterator avec le foreach
d'une manière récursive.
À l'intérieur du foreach
, la valeur du tableau est ensuite comparée à votre valeur de recherche. S'il ne correspond pas, il continue avec la valeur suivante. Mais s'il correspond aux méthodes getDepth()
et getSubIterator()
sur l'itérateur récursif, elles sont utilisées pour créer la matrice de clés.
L'exemple ne la sortie suivante:
Start, Item 1, Item 2_1, Item 2_1_1, x
Ce qui correspond à votre description dans la question. Parce que ce sont des itérateurs, vous pouvez également implémenter cela dans une classe qui lui est propre. Ce qui suit classe Iterator
permet non seulement de faire l'arbre-traversal sur le tableau fourni dans le constructeur, mais a aussi une méthode nommée getKeys()
qui retourne un tableau contenant toutes les clés du niveau le plus bas à la profondeur actuelle:
/**
* Class ArrayRecursiveKeysIterator
*/
class ArrayRecursiveKeysIterator extends RecursiveIteratorIterator
{
/**
* @param array $array
*/
public function __construct(array $array)
{
parent::__construct(new RecursiveArrayIterator($array));
}
/**
* @return array keys
*/
public function getKeys()
{
for ($k = [], $i = 0, $m = $this->getDepth(); $i <= $m; $i++)
$k[] = $this->getSubIterator($i)->key();
return $k;
}
}
Il est alors plus facile à utiliser (et probablement aussi pour d'autres scénarios). Donc, d'abord un exemple d'utilisation de base. Parcourez le tableau pour afficher toutes les clés de chaque valeur.Instancier le iterator pour votre tableau et la sortie des clés par chaque valeur:
$it = new ArrayRecursiveKeysIterator($array);
foreach ($it as $value) {
echo implode(', ', $it->getKeys()), ', ', $value, "\n";
}
Cela crée la sortie suivante:
Start, Item 1, 0, Item 1_1
Start, Item 1, Item 2_1, Item 2_1_1, x
Start, Item 1, 1, Item 3_1
Start, 0, Item 2
Start, 1, Item 3
Dans votre scénario, vous voulez aussi de filtrer l'itérateur base d'une valeur spécifique (ici la chaîne "x"
) que vous pouvez facilement faire en utilisant le RegexIterator
qui est un FilterIterator
. Voilà donc votre scénario:
$it = new ArrayRecursiveKeysIterator($array);
$filter = new RegexIterator($it, '~^x$~');
foreach ($filter as $value) {
echo implode(', ', $it->getKeys()), ', ', $value, "\n";
}
Et ici la sortie.
Start, Item 1, Item 2_1, Item 2_1_1, x
Comme vous pouvez le voir, il est filtré pour la valeur que vous êtes intéressé par
D'autres questions connexes vous « re probablement intéressé sont:
Vous pouvez essayer avec 'serialize()' – fedorqui
Découvrez des algorithmes de recherche graphique, comme BFS et DFS. –
array_search()? –