あなたが抱えている問題には、再帰および/またはツリートラバーサルが含まれます。RecursiveArrayIteratorPHP は、およびを使用した配列のツリー トラバーサルをサポートしていますRecursiveIteratorIterator。
すべての親配列のすべてのキーを取得するには、最初のレベルから現在の深さまで取得してキーを取得する必要があります。RecursiveIteratorIteratorこれは、メソッドでもサポートされていgetSubIterator()ます。マニュアルにはあまり詳しく記載されていないので、一例を次に示します。
$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";
}
この例では、まずRecursiveArrayIteratorwith your$arrayを作成します。ツリー トラバーサルを有効にするために、 にラップされますRecursiveIteratorIterator。これは、$it-iterator を と一緒にforeach再帰的に使用するために必要です。
then内foreachで、配列値が検索値に対してチェックされます。一致しない場合は、次の値に進みます。
ただし、一致する場合は、再帰反復子のgetDepth()andgetSubIterator()メソッドを使用してキーの配列を作成します。
この例では、次の出力が行われます。
Start, Item 1, Item 2_1, Item 2_1_1, x
質問の説明と一致します。
これらは反復子であるため、それを独自のクラスに実装することもできます。次のIteratorクラスでは、コンストラクターで提供された配列に対してツリー トラバーサルを実行できるだけでなくgetKeys()、最下位レベルから現在の深さまでのすべてのキーを含む配列を返すという名前のメソッドもあります。
/**
* 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;
}
}
これにより、より使いやすくなります (おそらく他のシナリオでも同様です)。では、まず基本的な使用例をいくつか。配列を調べて、各値のすべてのキーを表示します。配列の反復子をインスタンス化し、各値ごとにキーを出力します。
$it = new ArrayRecursiveKeysIterator($array);
foreach ($it as $value) {
echo implode(', ', $it->getKeys()), ', ', $value, "\n";
}
これにより、次の出力が作成されます。
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
あなたのシナリオでは、特定の値 (ここでは string "x") に基づいてイテレータをフィルタリングすることも必要RegexIteratorですFilterIterator。これがあなたのシナリオです:
$it = new ArrayRecursiveKeysIterator($array);
$filter = new RegexIterator($it, '~^x$~');
foreach ($filter as $value) {
echo implode(', ', $it->getKeys()), ', ', $value, "\n";
}
そしてここで出力:
Start, Item 1, Item 2_1, Item 2_1_1, x
ご覧のとおり、関心のある値でフィルター処理されています。
おそらく関心のあるその他の関連する質問は次のとおりです。