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'
    )
);

如果我编写 i 函数并传递一个说 id 1 的变量,有人可以告诉我如何返回一个仅包含所有子元素的 id 的一维数组。例如。

从前面的数组中,如果我传递 1 的 id,我希望函数返回 1、2,因为 2 是子元素的 id 元素。所以如果我通过它 2,它应该只返回 2,因为它没有任何孩子。

希望你能理解我,如果你能帮助我,谢谢你...

请注意,这可以是无限的,这意味着每个父类别可以有无限的子类别或子类别。

4

1 回答 1

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]

迭代器将使您的数组完全可遍历。这意味着,您可以foreach将整个阵列视为平面阵列。通常,它只会返回叶子 (1, 0, 0, Shirts, ...),但由于我们给了它SELF_FIRST选项,它也会返回包含叶子的数组。试着var_dump在 foreach 里面放一个看看。

换句话说,这

foreach ($iterator as $val) {

将遍历数组中的每个值。

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

此行将仅考虑数组并检查您传递给findById函数的 ID。如果存在,则将 ID 添加到函数将返回的数组中。所以这将解决问题1:找到从哪里开始。

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

如果数组有一个项目“孩子”(它应该是孩子顺便说一句),它将递归地从该项目中获取所有 ID 并将它们添加到返回的数组中:

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

接受一个数组(第array_walk_recursive一个参数)并将叶子的值和键传递给回调函数(第二个参数)。回调函数仅检查叶子是否为 ID 值,然后将其添加到返回数组中。如您所见,我们使用的是对返回数组的引用。这是因为 usinguse ($ids)会在闭包范围内创建数组的副本,而我们需要真正的数组以便向其中添加项目。这将解决问题 2:添加所有子 ID。

于 2013-01-31T11:58:12.277 回答