views:

451

answers:

4

I have this multi-dimensional PHP array (below).


Array
(
    [0] => Array
        (
            [2] => [email protected]
        )

    [1] => Array
        (
            [4] => [email protected]
        )

    [2] => Array
        (
            [3908] => [email protected]
        )

    [3] => Array
        (
            [2548] => [email protected]
        )

    [4] => Array
        (
            [3099] => [email protected]
        )

    [5] => Array
        (
            [5283] => [email protected]
        )

)


I was wondering how could I merge? or combine? or simply do it like this using PHP (below).


Array
(
    [2] => [email protected]
    [4] => [email protected]
    [3908] => [email protected]
    [2548] => [email protected]
    [3099]  => [email protected]
    [5283]  => [email protected]
)

Help

+4  A: 

The following will take your initial code and translate it to your desired output:

$new = array();
foreach($old as $key => $inner_array)
{
    $new += $inner_array;
}

(Where $old is your original)

This will retain keys and values. Note that this is making use of the array union operator +, and any duplicate keys in the target array will not be overwritten.

See the documentation page here for an explanation on why you won't use merge (3rd example):

array_merge

byte
You'll lose the keys with array_merge. You'd have to use the + operator instead.
scronide
Good note about array_merge()—like a lot of PHP functions, it doesn't work exactly as expected.
Drew Stephens
You've introduced a syntax error: "= +=".
scronide
d'oh :) nice catch, thanks. late here, heh.
byte
I hope you don't mind but I've added a link to the array union operator documentation - I wasn't aware of it before.
therefromhere
Don't mind at all, more info to make the answer clearer the better :)
byte
A: 

Simply go through the array and store to another.

$a = array( 0 => array(1) , 1=> array(3) );
$another=array();
foreach ($a as $k=>$v){    
    foreach ($v as $y=>$z){
        $another[$k]=$z;
    }    
}
print_r($another);
ghostdog74
This is unnecessarily slow, and is big O of n^2. You can simply concatenate arrays, which will retain keys and values.
byte
You lose the keys relying on array_push. You'd have to replace that with $another[$y] = $z instead.
scronide
thanks...didn't notice the keys need to be intact
ghostdog74
edited according to scronide suggestion.
ghostdog74
I didn't feel it was fair to downvote this answer, though it may not be elegant, the thought was there as demonstrated by the correction. Even though its not the most elegant, it does do the job. I'm +1 to bring it from -1 to 0.
byte
A: 

How about this?


foreach( $old_arr as $old )
{
    $key = key( $old[0] );
    $new[ $key ] = $old[0][$key];
}

EDIT: Never mind didn't realize previous answer was corrected.

Kane Wallmann
This won't work because it assumes the child array values are keyed on 0, when none of those in the example are.
scronide
+2  A: 

You can "promote" the second level elements to first level elements via call_user_func_array(). And while array_merge() re-indexes the array, array_replace() does not but retains the original keys which makes this a one-liner:

$a = call_user_func_array('array_replace', $a);

test:

<?php
$a = array (
  array (2 => '[email protected]'),
  array (4 => '[email protected]'),
  array (3908 => '[email protected]'),
  array (2548 => '[email protected]'),
  array (3099 => '[email protected]'),
  array (5283 => '[email protected]'),
);
$a = call_user_func_array('array_replace', $a);
var_dump($a);
VolkerK
This does the trick, but it's important to note that array_replace() only exists since PHP 5.3.0 (20090630).
scronide