tags:

views:

249

answers:

4

Hi,

I am trying to create a single array that contains all of the values of an existing multidimensional array. This is what I have so far...

    function MaxArray($arr) {

    foreach ($arr as $value) {

        if (is_array($value)) {
            MaxArray($value);
        } else {
            $array[] = $value;
        }
    }
print_r($array);

}

$arr = array(array(141,151,161), 2, 3, array(101, 202, array(303,404, array(1,2))));

MaxArray($arr);

When I execute this code, I get this response from the print_r function...

Array ( [0] => 141 [1] => 151 [2] => 161 ) Array ( [0] => 1 [1] => 2 ) Array ( [0] => 303 [1] => 404 ) Array ( [0] => 101 [1] => 202 ) Array ( [0] => 2 [1] => 3 ) 

As you can see, this is not what I am looking for and I can't figure out how to combine all of the values in the multidimensional array into a single array. Can anyone please point me in the right direction here? Thanks!

+5  A: 

What you're trying to do is often called 'array flattening', so ArrayFlatten is probably a better name for a function than MaxArray (since the latter sounds like it'll return the highest value in the array, which max does very well). ArrayFlatten could be written like this:

function ArrayFlatten($array, $return) {
  for ($x = 0; $x < count($array); $x++) {
    if(is_array($array[$x])) {
      $return = ArrayFlatten($array[$x], $return);
    }
    else {
      if($array[$x]) {
        $return[] = $array[$x];
      }
    }
  }

  return $return;
}

And used like this:

$myarray = array('a','b',array(array(array('x'),'y','z')),array(array('p')));    
$res = ArrayFlatten($myarray,array());

To get this:

Array
(
    [0] => a
    [1] => b
    [2] => x
    [3] => y
    [4] => z
    [5] => p
)

From here.

Dominic Rodger
Thanks for the quick reply, your function worked great except it is showing a bunch of notice errors that look like this...Notice: Undefined offset: 3 in /Users/Devin/Sites/mywebapp/query.php on line 16Any idea what is causing those errors?
Devin Lewis
The `$x <= count($array)` test should be `$x < count($array)`. Alternatively, use a foreach loop, which will work with non-integer indices. You can then adapt the function to preserve string keys (though you'll need to decide what to do about string-key collisions).
outis
@Devin - apologies, @outis - thanks. Edited!
Dominic Rodger
@Dominic: make $return pass-by-reference for efficiency's sake. You can also set a default value of `array()` for `$return` to simplify usage.
outis
A: 

$array is recreated and printed in every execution of MaxArray(). You need to build it up over all recursive executions. I think the best way to do it is to have the MaxArray() function return that array rather than print it out. ... and as I type this, Dominic Rodger has just done it for you!

Scott Saunders
A: 

the function should take a reference to the result array, which will never change.

function flatten($cur, & $result) { ... flatten($x, $result); ... }

an example here: http://davidwalsh.name/flatten-nested-arrays-php

jspcal
A: 

Here's another variant that illustrates use of foreach and preserving (some) string keys.

function array_flatten($array) {
    $rslt = array();
    foreach ($array as $key => $val) {
        if (is_array($val)) {
            $rslt = array_merge($rslt, array_flatten($val));
        } elseif (is_int($key)) {
            $rslt[] = $val;
        } else {
            // for string keys, earlier values are overwritten with later ones
            $rslt[$key] = $val;
        }
    }
    return $rslt;
}

For different collision behavior, change the $rslt[$key] = $val; line.

outis