Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to unflatten a multidimensional array (where original key access path is stored as a single key) in PHP?

I'm using the following function to flatten a multidimensional array:

function flatten($array, $prefix = '') {
    $result = array();
    foreach($array as $key=>$value) {
        if(is_array($value)) {
            $result = $result + flatten($value, $prefix . $key . '.');
        }
        else {
            $result[$prefix . $key] = $value;
        }
    }
    return $result;
}

I'd like to create a matching function, unflatten, that will reverse the process(e.g create a child array if the key has a . in it). Any ideas?

like image 274
Duru Can Celasun Avatar asked Feb 19 '23 20:02

Duru Can Celasun


1 Answers

Use parse_str to get this done.just try below.

function flatten($array, $prefix = '') {
    $result = array();
    foreach($array as $key=>$value) {
        if(is_array($value)) {
            $result = $result + flatten($value, $prefix . $key . '.');
        }
        else {
            $result[$prefix . $key] = $value;
        }
    }
    return $result;
}

function unflatten($array,$prefix = '')
{
    $result = array();
    foreach($array as $key=>$value)
    {
        if(!empty($prefix))
        {
            $key = preg_replace('#^'.preg_quote($prefix).'#','',$key);
        }
        if(strpos($key,'.') !== false)
        {
            parse_str('result['.str_replace('.','][',$key)."]=".$value);
        }
        else $result[$key] = $value;
    }
    return $result;
}
$source    = array('a'=>'d','b',array('a'=>'c','d'));
$flattened = flatten($source,'__');
echo "<pre>";
echo "source array :<br/>";
print_r($source);
echo "flatten result:<br/>";
print_r($flattened);
echo "unflatten result:<br/>";
print_r(unflatten($flattened,'__'));
echo "<pre/>";

Outputs:

source array :
Array
(
    [a] => d
    [0] => b
    [1] => Array
        (
            [a] => c
            [0] => d
        )

)
flatten result:
Array
(
    [__a] => d
    [__0] => b
    [__1.a] => c
    [__1.0] => d
)
unflatten result:
Array
(
    [a] => d
    [0] => b
    [1] => Array
        (
            [a] => c
            [0] => d
        )

)
like image 193
Lake Avatar answered Feb 22 '23 10:02

Lake