У меня есть четыре уровня вложенного массива, как это:
$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' => []
]
]
]
]
]
]
]
];
Теперь я хотел бы удалить некоторые элементы массива на основе некоторых правил. Допустим, для простоты мы хотели бы удалить элементы массива с идентификатором, равным one.one.two
или one.two.one
.
Я изучал некоторые ответы, представленные на stackoverflow, и пытался применить их для решения моей проблемы, но ничего не получалось. Самое сложное - это сбросить часть массива, где это не самая дальняя точка массива.
Я пытался это отметить, на каком уровне я хочу удалить массивы, а затем пытался сбросить их, используя индекс этих массивов.
$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 [];
}
Я также пытался использовать итератор так:
$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;
}
}
но мне нужен способ сбросить массив при циклическом переборе итератора.
Я бы хотел получить такой вывод:
$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' => []
]
]
]
]
]
]
]
];
Я бы очень признателен за помощь в том, как решить эту проблему более эффективным способом. Спасибо.