1

ID を渡した場合、すべての子要素から ['id'] を取得するにはどうすればよいですか。

これは私の配列です...

$array = Array
(
    '0' => Array
    (
        'id' => 1,
        'parent_id' => 0,
        'order_pos' => 0,
        'title' => 'Shirts',
        'childs' => Array
        (
            '0' => Array
            (
                'id' => 2,
                'parent_id' => 1,
                'order_pos' => 0,
                'title' => 'Small Shirts',
            )
        )
    ),
    '1' => Array
    (
        'id' => 3,
        'parent_id' => 0,
        'order_pos' => 0,
        'title' => 'Cameras'
    )
);

関数を書いて id 1 の変数を渡すと、すべての子要素の id だけで 1 次元配列を返す方法を誰か教えてください。

前の配列から、1 の id を渡すと、2 は子要素の id 要素であるため、関数は 1、2 を返します。したがって、2 を渡すと、子がないため 2 のみが返されます。

私はあなたが私を理解してくれることを願っています.

これは無制限にできることに注意してください。つまり、各親カテゴリは無制限のサブカテゴリまたは子を持つことができます。

4

1 に答える 1

2

基本的に、解決する必要がある 2 つの問題があります。

  1. 指定された ID の配列全体を検索して開始します。
  2. ID が見つかったら、子からすべての ID を取り出します。

これはうまくいきます:

function findIds(array $array, $id)
{
    $ids = array();
    $iterator = new RecursiveIteratorIterator(
        new RecursiveArrayIterator($array),
        RecursiveIteratorIterator::SELF_FIRST
    );

    foreach ($iterator as $val) {
        if (is_array($val) && isset($val['id']) && $val['id'] === $id) {
            $ids[] = $val['id'];
            if (isset($val['childs'])) {
                array_walk_recursive(
                    $val['childs'],
                    function($val, $key) use (&$ids) {
                        if ($key === 'id') {
                            $ids[] = $val;
                        }
                    }
                );
            }
        }
    }

    return $ids;
}

print_r( findIds($array, 1) ); // [1, 2]
print_r( findIds($array, 2) ); // [2]
print_r( findIds($array, 3) ); // [3]

Iterators は、配列を完全にトラバース可能にします。つまり、foreach配列全体をフラットな配列のように扱うことができます。通常、葉 (1、0、0、シャツなど) のみを返しますが、SELF_FIRSTオプションを指定したため、葉を保持する配列も返されます。var_dumpforeach の中に a を入れてみてください。

つまり、これは

foreach ($iterator as $val) {

配列内のすべての値を調べます。

if (is_array($val) && isset($val['id']) && $val['id'] === $id) {

この行は配列のみを考慮し、関数に渡した ID をチェックしfindByIdます。存在する場合、関数によって返される配列に ID が追加されます。これで問題 1 が解決されます。

if (isset($val['childs'])) { 

配列に「子」という項目がある場合 (これは子である必要があります)、その項目からすべての ID を再帰的に取得し、返された配列にそれらを追加します。

array_walk_recursive(
    $val['childs'],
    function($val, $key) use (&$ids) {
        if ($key === 'id') {
            $ids[] = $val;
        }
    }
);

は配列 (第array_walk_recursive1 引数) を受け取り、葉の値とキーをコールバック関数 (第 2 引数) に渡します。コールバック関数は、葉が ID 値であるかどうかを確認し、それを戻り配列に追加するだけです。ご覧のとおり、戻り配列への参照を使用しています。これは、use ($ids)アイテムを追加するために実際の配列が必要なときに、クロージャー スコープ内に配列のコピーを作成するためです。これで問題 2 が解決されます: すべての子 ID を追加します。

于 2013-01-31T11:58:12.277 に答える