简体   繁体   English

如何删除PHP数组中不包含特定值的分支

[英]How to remove branches that don't contain a certain value in a php array

I've spent the day playing with deceze's answer but I'm no closer to making it work. 我已经花了整整一天的时间来解决deceze的答案,但是我离使之工作更近了。 I may have part of it, but not sure how to get recursion in array_filter. 我可能有一部分,但不确定如何在array_filter中进行递归。

My Array looks like this (sample): 我的数组如下所示(示例):

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
                                                )

                                        )

                                )


                        )

                )

Now lets say I try to extract just the parts of the array relevent to the following keypair: 现在让我们说我尝试将数组relevent的部分仅提取到以下密钥对:

S => 6067. S => 6067。

I'd like the result to look like: 我希望结果看起来像:

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
                                                )


                                        )

                                )


                        )

                )
    )
)

What I cannot get my head arround is should I be creating a new array or using array filter. 我无法理解的是应该创建新数组还是使用数组过滤器。

Playing with deceze code I've got the search working using the following: 使用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;

}

But if I try to process with, 但是如果我尝试处理,

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

I get the original array which leads me to think I have to get recursion running on the array_filter query. 我得到了原始数组,这使我认为我必须在array_filter查询上运行递归。

At this point I just go blank. 在这一点上,我只是一片空白。

Additionally, the array keys will need to be reindexed on the produced new array. 此外,阵列键将需要在产生的新阵列上重新索引。 Any ideas? 有任何想法吗?

--Additional 7/7/14 -其他7/7/14

How about if I try to build a new array from the old one? 如果我尝试从旧阵列构建新阵列,该怎么办?

I'm trying: 我正在努力:

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;
        } 

    }

}

But cannot work out how to pass the new array out of the function? 但是无法解决如何将新数组传递出函数吗?

Tried removing branches that don't match using: 尝试使用以下方法删除不匹配的分支:

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

}

But I believe it is the wrong way as it does work at the bottom of the array but not back up towards the top as siblings make result true. 但是我相信这是错误的方法,因为它确实在数组的底部起作用,但不会随着同级使结果为真而返回顶部。 Also this won't reindex the array keys. 同样,这不会重新索引数组键。

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]);
});

To express the algorithm in words: you descend down into the array first, following all ChildCats branches to their end. 用语言表达算法:首先下降到数组中,然后跟随所有ChildCats分支到其末端。 In each level you return the values as they are back to the caller if they match your test or if they have children, or you return an emptied array (you could also return false if you prefer). 在每个级别中,如果它们与您的测试匹配有子级,则返回它们返回给调用方的值,或者返回一个空数组(如果愿意,还可以返回false )。 If some child turns out empty, you prune it with unset . 如果有些孩子原来空的,你清理, unset

I have implemented the test as a callback function here for best reusability of the code. 为了实现代码的最佳重用性,我在此处将测试实现为回调函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM