如何删除不包含php数组中某个值的分支

时间:2014-06-30 07:49:27

标签: php arrays recursion

我花了一天时间玩deceze的答案,但我没有接近让它发挥作用。我可能有部分内容,但不确定如何在array_filter中获取递归。

My Array看起来像这样(样本):

Array
(
    [name] => root
    [ChildCats] => Array
        (
            [0] => Array
                (
                    [name] => Air Conditioning
                    [ChildCats] => Array
                        (
                            [0] => Array
                                (
                                    [name] => Ducted Air Conditioning
                                    [ChildCats] => Array
                                        (
                                            [0] => Array
                                                (
                                                    [name] => Supply & Install
                                                    [ChildCats] => Array
                                                        (
                                                            [0] => Array
                                                                (
                                                                    [name] => Daiken
                                                                    [S] => 6067
                                                                )

                                                        )

                                                )

                                            [1] => Array
                                                (
                                                    [name] => Supply Only
                                                    [ChildCats] => Array
                                                        (
                                                            [0] => Array
                                                                (
                                                                    [name] => Mitsubishi
                                                                    [S] => 6026
                                                                )

                                                        )

                                                )

                                        )

                                )

                            [1] => Array
                                (
                                    [name] => Split System Air Conditioning
                                    [ChildCats] => Array
                                        (
                                            [0] => Array
                                                (
                                                    [name] => Supply & Install
                                                    [ChildCats] => Array
                                                        (
                                                            [0] => Array
                                                                (
                                                                    [name] => Daiken
                                                                    [S] => 6067
                                                                )

                                                            [1] => Array
                                                                (
                                                                    [name] => Fujitsu Split Air Conditioning Systems
                                                                    [S] => 6464
                                                                )

                                                            [2] => Array
                                                                (
                                                                    [name] => Mitsubishi Electric Split Air Conditioning Systems
                                                                    [S] => 6464
                                                                )

                                                        )

                                                )

                                        )

                                )

                        )

                )

            [1] => Array
                (
                    [name] => Appliance / White Goods
                    [ChildCats] => Array
                        (
                            [0] => Array
                                (
                                    [name] => Clearance
                                    [S] => 6239
                                )

                            [1] => Array
                                (
                                    [name] => Cooktops
                                    [ChildCats] => Array
                                        (
                                            [0] => Array
                                                (
                                                    [name] => Ceramic Cooktops
                                                    [S] => 6239
                                                )

                                            [1] => Array
                                                (
                                                    [name] => Element Cooktops
                                                    [S] => 6067
                                                )

                                            [2] => Array
                                                (
                                                    [name] => Gas Cooktops
                                                    [S] => 6239
                                                )

                                            [3] => Array
                                                (
                                                    [name] => Induction Cooktops
                                                    [S] => 6239
                                                )

                                        )

                                )


                        )

                )

现在让我说我尝试将数组的各个部分提取到以下密钥对:

S => 6067。

我希望结果如下:

Array
(
    [name] => root
    [ChildCats] => Array
        (
            [0] => Array
                (
                    [name] => Air Conditioning
                    [ChildCats] => Array
                        (
                            [0] => Array
                                (
                                    [name] => Ducted Air Conditioning
                                    [ChildCats] => Array
                                        (
                                            [0] => Array
                                                (
                                                    [name] => Supply & Install
                                                    [ChildCats] => Array
                                                        (
                                                            [0] => Array
                                                                (
                                                                    [name] => Daiken
                                                                    [S] => 6067
                                                                )

                                                        )

                                                )

                                        )

                                )

                            [1] => Array
                                (
                                    [name] => Split System Air Conditioning
                                    [ChildCats] => Array
                                        (
                                            [0] => Array
                                                (
                                                    [name] => Supply & Install
                                                    [ChildCats] => Array
                                                        (
                                                            [0] => Array
                                                                (
                                                                    [name] => Daiken
                                                                    [S] => 6067
                                                                )


                                                        )

                                                )

                                        )

                                )

                        )

                )

            [1] => Array
                (
                    [name] => Appliance / White Goods
                    [ChildCats] => Array
                        (

                            [0] => Array
                                (
                                    [name] => Cooktops
                                    [ChildCats] => Array
                                        (

                                            [0] => Array
                                                (
                                                    [name] => Element Cooktops
                                                    [S] => 6067
                                                )


                                        )

                                )


                        )

                )
    )
)

我无法理解的是我应该创建一个新数组还是使用数组过滤器。

使用deceze代码我已经使用以下内容进行了搜索:

function recursive_assoc_in_array(array $haystack,  array $needle, $childKey = 'ChildCats') {

    if (array_intersect_assoc($haystack, $needle)) {
        echo "Found via array_intersect_assoc ".$haystack[name]."\n";
        return true;    
    } 

    foreach ($haystack[$childKey] as $child) {

         if (recursive_assoc_in_array($child, $needle, $childKey)) return true;
    }
    return false;

}

但如果我尝试处理,

$array = array_filter($array, function (array $values) {
    return recursive_assoc_in_array($values, array('S' => '6067'));
});

我得到原始数组,这使我认为我必须在array_filter查询上运行递归。

此时我只是空白。

此外,数组键需要在生成的新数组上重新编制索引。有什么想法吗?

- 额外的7/7/14

如果我尝试从旧数组构建一个新数组怎么样?

我正在尝试:

function exploreArrayandAdd($Array) {

    if ($Array['ChildCats']) {

        foreach ($Array['ChildCats'] as $key => $value) {
            $NewArray['ChildCats'][] = exploreArrayandAdd($value);
        }

    } else {

        if ($Array['S'] == 6026) {
            //echo "1";
            return $Array;
        } 

    }

}

但是无法弄清楚如何将新数组传递出函数?

尝试删除不匹配的分支:

function exploreArray(&$Array) {

    if ($Array['ChildCats']) {

        foreach ($Array['ChildCats'] as $key => $value) {
            $result = exploreArray($Array['ChildCats'][$key]);

            if ($result === false)
                unset($Array['ChildCats'][$key]);

        }

    } else {
        //  print_r($Array);
        if ($Array['S'] == 6026) {
            return true;
        } else {
            unset($Array);
            return false;
        }

    }
    //if ($NoChildCat==true) print_r($Array);

}

但我认为这是错误的方式,因为它在阵列的底部工作,但没有回到顶部,因为兄弟姐妹的结果是真的。 这也不会重新索引数组键。

1 个答案:

答案 0 :(得分:0)

function recursive_array_filter(array $array, $childKey, callable $test) {
    if (isset($array[$childKey]) && is_array($array[$childKey])) {
        foreach ($array[$childKey] as $key => &$child) {
            if (!$child = recursive_array_filter($child, $childKey, $test)) {
                unset($array[$childKey][$key]);
            }
        }
        if (!$array[$childKey]) {
            unset($array[$childKey]);
        }
    }
    return !empty($array[$childKey]) || $test($array) ? $array : [];
}

$array = recursive_array_filter($array, 'ChildCats', function (array $array) {
    return array_intersect_assoc($array, ['S' => 6026]);
});

用语言表达算法:首先下降到数组中,然后跟随所有ChildCats个分支到它们的末尾。在每个级别中,如果值匹配您的测试(如果他们有孩子),或者您返回一个空的数组(如果您还是false,则返回给调用者的值)喜欢)。如果某个孩子变空,则用unset修剪它。

我已将测试作为回调函数实现,以实现代码的最佳可重用性。