Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using string path to delete element from array

Tags:

arrays

php

unset

I have array like that

$arr = [
   'baz' => [
      'foo' => [
         'boo' => 'whatever'
     ]
   ]
];

Is there anyway to unset ['boo'] value using string input?

Something like that

    $str = 'baz->foo->boo';
    function array_unset($str, $arr) {

    // magic here

    unset($arr['baz']['foo']['boo']);
    return $arr;
    }

This answer was awesome, and it's made first part of my script run Using a string path to set nested array data . But It's can't reverse. P.S. eval() is not an option :(

like image 925
remtsoy Avatar asked May 22 '13 17:05

remtsoy


2 Answers

Since you can't call unset on a referenced element, you need to use another trick:

function array_unset($str, &$arr)
{
    $nodes = split("->", $str);
    $prevEl = NULL;
    $el = &$arr;
    foreach ($nodes as &$node)
    {
        $prevEl = &$el;
        $el = &$el[$node];
    }
    if ($prevEl !== NULL)
        unset($prevEl[$node]);
    return $arr;
}

$str = "baz->foo->boo";
array_unset($str, $arr);

In essence, you traverse the array tree but keep a reference to the last array (penultimate node), from which you want to delete the node. Then you call unset on the last array, passing the last node as a key.

Check this codepad

like image 74
huysentruitw Avatar answered Sep 18 '22 15:09

huysentruitw


This one is similar to Wouter Huysentruit's. Difference is that it returns null if you pass on an invalid path.

function array_unset(&$array, $path)
{
    $pieces = explode('.', $path);
    $i = 0;
    while($i < count($pieces)-1) {
        $piece = $pieces[$i];
        if (!is_array($array) || !array_key_exists($piece, $array)) {
            return null;
        }
        $array = &$array[$piece];
        $i++;
    }
    $piece = end($pieces);
    unset($array[$piece]);
    return $array;
}
like image 29
brunettdan Avatar answered Sep 21 '22 15:09

brunettdan