首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >从多维嵌套数组中移除部分数组

从多维嵌套数组中移除部分数组
EN

Stack Overflow用户
提问于 2019-05-29 06:09:04
回答 1查看 206关注 0票数 0

我有一个四层的嵌套数组,如下所示:

代码语言:javascript
复制
$array = [
    [
        'website' => [
            'id' => 'one'
        ],
        'children' => [
            [
                'website' => [
                    'id' => 'one.one'
                ],
                'children' => [
                    [
                        'website' => [
                            'id' => 'one.one.one'
                        ],
                        'children' => [
                            [
                                'website' => [
                                    'id' => 'one.one.one.one'
                                ],
                                'children' => []
                            ],
                            [
                                'website' => [
                                    'id' => 'one.one.one.two'
                                ],
                                'children' => []
                            ]
                        ]
                    ],
                    [
                        'website' => [
                            'id' => 'one.one.two'
                        ],
                        'children' => [
                            [
                                'website' => [
                                    'id' => 'one.one.two.one'
                                ],
                                'children' => []
                            ],
                            [
                                'website' => [
                                    'id' => 'one.one.two.two'
                                ],
                                'children' => []
                            ]
                        ]
                    ]
                ]
            ],
            [
                'website' => [
                    'id' => 'one.two'
                ],
                'children' => [
                    [
                        'website' => [
                            'id' => 'one.two.one'
                        ],
                        'children' => [
                            [
                                'website' => [
                                    'id' => 'one.two.one.one'
                                ],
                                'children' => []
                            ],
                            [
                                'website' => [
                                    'id' => 'one.two.one.two'
                                ],
                                'children' => []
                            ]
                        ]
                    ],
                    [
                        'website' => [
                            'id' => 'one.two.two'
                        ],
                        'children' => [
                            [
                                'website' => [
                                    'id' => 'one.two.two.one'
                                ],
                                'children' => []
                            ],
                            [
                                'website' => [
                                    'id' => 'one.two.two.two'
                                ],
                                'children' => []
                            ]
                        ]
                    ]
                ]
            ]
        ]
    ]
];

现在,我想根据一些规则删除一些数组元素。为简单起见,假设我们想删除'id‘等于one.one.twoone.two.one的数组元素。

我正在研究stackoverflow上提供的一些答案,并试图应用它们来解决我的问题,但收效甚微。最大的变化是取消数组中不是数组中最远点的部分。

我尝试这样做是为了记录我想要在哪个级别删除数组,然后尝试使用这些数组索引取消设置它们。

代码语言:javascript
复制
$pointer = [];
foreach($array as $key => $level1) {
    $level1pointer = $key;
    $pointer[] = markToDelete($level1, $level1pointer);
    foreach($level1['children'] as $key => $level2) {
        $level2pointer = $key;
        $pointer[] = markToDelete($level2, $level1pointer, $level2pointer);
        foreach($level2['children'] as $key => $level3) {
            $level3pointer = $key;
            $pointer[] = markToDelete($level3, $level1pointer, $level2pointer, $level3pointer);
            foreach($level3['children'] as $key => $level4) {
                $level4pointer = $key;
                $pointer[] = markToDelete($level4, $level1pointer, $level2pointer, $level3pointer, $level4pointer);
            }
        }
    }
}

function markToDelete($array, $level1 = null, $level2 = null, $level3 = null, $level4 = null) {
    $exclusionList = [
        'one.one.two',
        'one.two.one'
    ];

    if (!empty($array['website']) && in_array($array['website']['id'], $exclusionList)) {
        print_r('marking for deletion: '. $array['website']['id'] . PHP_EOL);
        return [
            'id' => $array['website']['id'],
            'level1' => $level1,
            'level2' => $level2,
            'level3' => $level3,
            'level4' => $level4
        ];
    }
    return [];
}

我也试着这样使用迭代器:

代码语言:javascript
复制
$it = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($array), \RecursiveIteratorIterator::LEAVES_ONLY);
$newArray = [];
foreach($it as $key => $value) {
    $exclusionList = [
        'one.one.two',
        'one.two.one'
    ];
    if(!in_array($value, $exclusionList)) {
        print_r(sprintf('value: %s is ready to be deleted', $value).PHP_EOL);
        $newArray[] = $value;
    }
}

但我需要一种方法来在遍历迭代器时取消设置数组。

我希望得到这样的输出:

代码语言:javascript
复制
$array = [
    [
        'website' => [
            'id' => 'one'
        ],
        'children' => [
            [
                'website' => [
                    'id' => 'one.one'
                ],
                'children' => [
                    [
                        'website' => [
                            'id' => 'one.one.one'
                        ],
                        'children' => [
                            [
                                'website' => [
                                    'id' => 'one.one.one.one'
                                ],
                                'children' => []
                            ],
                            [
                                'website' => [
                                    'id' => 'one.one.one.two'
                                ],
                                'children' => []
                            ]
                        ]
                    ],
                ]
            ],
            [
                'website' => [
                    'id' => 'one.two'
                ],
                'children' => [
                    [
                        'website' => [
                            'id' => 'one.two.two'
                        ],
                        'children' => [
                            [
                                'website' => [
                                    'id' => 'one.two.two.one'
                                ],
                                'children' => []
                            ],
                            [
                                'website' => [
                                    'id' => 'one.two.two.two'
                                ],
                                'children' => []
                            ]
                        ]
                    ]
                ]
            ]
        ]
    ]
];

如果你能帮助我以更有效的方式解决这个问题,我将非常感激。谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-05-29 07:39:13

下面是一个递归函数,它将执行您想要的操作。它遍历数组,查找其网站id在要删除的id列表中的子节点,并取消对它们的设置。请注意,由于您有额外的顶级数组,因此需要对这些值迭代函数。

代码语言:javascript
复制
function delete_entries(&$array, $ids_to_delete) {
    foreach ($array['children'] as $index => &$child) {
        if (in_array($child['website']['id'], $ids_to_delete)) {
            unset($array['children'][$index]);
        }
        delete_entries($child, $ids_to_delete);
    }
}

foreach ($array as &$arr) {
    delete_entries($arr, array('one.one.two', 'one.two.one'));
}

var_export($array);

输出如您所愿,但太长了,不能在这里重现。请参阅demo on 3v4l.org

更新

上面的代码不会删除顶层的条目,因为数组结构与数组中的低层不同。这可以在外部foreach循环中处理:

代码语言:javascript
复制
$excluded = array('two', 'one.one.two', 'one.two.one');
foreach ($array as $key => &$arr) {
    if (in_array($arr['website']['id'], $excluded)) {
        unset($array[$key]);
    }
    else {
        delete_entries($arr, $excluded);
    }
}

Updated demo

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56350658

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档