Sakhri Houssem
Sakhri Houssem

Reputation: 1063

multidimensional array to one dimensional array recursively

I have this multidimensional array

$liste = [[1,2,3],5,[['x','y','z'],true]];

and I want to change it to one dimensionel array

$liste = [1,2,3,5,'x','y','z',true];

so i always have a problem that give me the same shape

function to_array($list){
    $out=[];
    if(!is_array($list)){
        return $list;
    }else{
        foreach($list as $line){
            $out[]= to_array($line);
        }
    }
    return $out;
}

where is the problem in this recursive function !!!

Upvotes: 0

Views: 742

Answers (2)

mickmackusa
mickmackusa

Reputation: 48100

array_walk_recursive() delivers the desired result from an array of indeterminate depth in a one-liner because it only visits the "leaf-nodes" -- effectively, you don't need to bother checking if an element is or is not an array.

array_walk_recursive() doesn't return an array, it returns true|false based on whether or not there was a failure.

&$flat is a variable which is "passed by reference". This means that $flat can act as a vehicle to transport the data from inside the function scope to outside the function scope. As the elements are traversed, each new value is pushed into $flat using square bracket syntax.

This is exactly what this function does best -- use it.

Code: (Demo)

$liste = [[1, 2, 3], 5, [['x', 'y', 'z'], true]];
array_walk_recursive($liste, function($v) use (&$flat){ $flat[] = $v; });
var_export($flat);

Output:

array (
  0 => 1,
  1 => 2,
  2 => 3,
  3 => 5,
  4 => 'x',
  5 => 'y',
  6 => 'z',
  7 => true,
)

Upvotes: 1

Nick
Nick

Reputation: 147286

The issue with your code is that you are pushing the result of to_array into $out, when what you want to do is use array_merge. Now since that requires both parameters to be arrays, when $list is not an array, you need to return an array containing the individual value. So change these lines:

    return $list;
        $out[]= to_array($line);

To:

    return array($list);
        $out = array_merge(to_array($line));

i.e.

function to_array($list){
    $out=[];
    if(!is_array($list)){
        return array($list);
    }else{
        foreach($list as $line){
            $out = array_merge($out, to_array($line));
        }
    }
    return $out;
}

And you will get the result that you want:

var_export(to_array($liste));

Output:

array (
  0 => 1,
  1 => 2,
  2 => 3,
  3 => 5,
  4 => 'x',
  5 => 'y',
  6 => 'z',
  7 => true,
)

Upvotes: 1

Related Questions