arcanine arcanine - 1 month ago 6
PHP Question

PHP how to delete deep keys progammatically

Imagine you have a deep array like this :

<?php
$array = ['hello' => ['deep' => 'treasure']];


Then you had an array of the keys to access the string 'treasure'

['hello', 'deep'];


How do you delete the string treasure if you did not know the depth of the array till run time

Edit:

My apologises I've definitely not provided enough information for what I'm looking to achieve

Here is some code I've come up with which does what I need but uses unsafe eval (keep in mind the target destination could be an array so array_walk_recursive won't work)

function iterator_keys($iterator, $outer_data) {
$keys = array();
for ($i = 0; $i < $iterator->getDepth() + 1; $i++) {
$sub_iterator = $iterator->getSubIterator($i);
$keys[$i] = ($i == 0 && is_object($outer_data)
|| $i > 0 && is_object($last_iterator->current())) ?
'->{"' . $sub_iterator->key() . '"}' :
'["' . $sub_iterator->key() . '"]';
$last_iterator = $sub_iterator;
}
return $keys;
}
function recursive_filter($data, callable $selector_function, $iterator = NULL) {
$iterator = $iterator ?? new RecursiveIteratorIterator(
new RecursiveArrayIterator($data),
RecursiveIteratorIterator::CHILD_FIRST
);
foreach ($iterator as $key => $value) {
if ($selector_function($value, $key, $iterator)) {
eval('unset($data' . implode('', iterator_keys($iterator, $data)) . ');');
}
}
return $data;
}


The intention is to have a deep data structure a function that evalutes each node and if it matches a condition then remove it from the data structure in place, if this can be done without eval that would be amazing but so far I think PHP can't programmatically delete something that is more than one level deep

Answer

Hello I think what you want is somethings like this

<?php    
$array = ['hello' => ['deep' => ['deep1' => 'treasure']]];
$keys = ["hello", "deep", "deep1"];

function remove_recursive(&$array, $keys, $level = 0)
{
    if ($level >= count($keys)) {
        return $array;
    }
    if (isset($array[$keys[$level]]) && $level == count($keys) - 1) {
        unset($array[$keys[$level]]);
    } elseif (isset($array[$keys[$level]])) {
        $array[$keys[$level]] = remove_recursive($array[$keys[$level]], $keys, $level + 1);
    }

    return $array;
}

var_dump(remove_recursive($array, $keys));
Comments