user2319551
user2319551

Reputation: 53

Merge deep rows of an array with 3 levels by second level keys

If I have an array which looks something like this:

Array
(
    [0] => Array
    (
        [DATA] => Array
        (
            VALUE1 = 1
            VALUE2 = 2
        )
    )
    [1] => Array
    (   
        [DATA] => Array
        (
            VALUE3 = 3
            VALUE4 = 4
        )
    )
)

And would like to turn it into this:

Array
(
    [0] => Array
    (
        [DATA] => Array
        (
            VALUE1 = 1
            VALUE2 = 2
            VALUE3 = 3
            VALUE4 = 4
        )
    )
)

I basically want to merge all the identical keys which are at the same level. What would be the best route to accomplish this? Could the array_merge() functions be of any use?

Upvotes: 5

Views: 3436

Answers (2)

mickmackusa
mickmackusa

Reputation: 47863

Spreading multidimensional array data inside of a array_merge_recursive() call will flatten your array and effectively remove the indexed first level.

New input array:

$array = [
    ['data1' => ['value1' => 1, 'value2' => 2]],
    ['data2' => ['value5' => 5, 'value6' => 6]],
    ['data1' => ['value3' => 3, 'value4' => 4]],
];

Demo

var_export(
    array_merge_recursive(...$array)
);

Output:

array (
  'data1' => 
  array (
    'value1' => 1,
    'value2' => 2,
    'value3' => 3,
    'value4' => 4,
  ),
  'data2' => 
  array (
    'value5' => 5,
    'value6' => 6,
  ),
)

To maintain the original array depth in the result, use nested loops to identify unique groups, push group references into the result array, and append subsequent group data with an array union assignment operator. Demo

$result = [];
foreach ($array as $set) {
    foreach ($set as $k => $row) {
        if (!isset($ref[$k])) {
            $ref[$k] = $set;
            $result[] =& $ref[$k];
            continue;
        }
        $ref[$k][$k] += $row;
    }
}
var_export($result);

Output:

array (
  0 => 
  array (
    'data1' => 
    array (
      'value1' => 1,
      'value2' => 2,
      'value3' => 3,
      'value4' => 4,
    ),
  ),
  1 => 
  array (
    'data2' => 
    array (
      'value5' => 5,
      'value6' => 6,
    ),
  ),
)

Upvotes: 0

Jon
Jon

Reputation: 437336

You can use array_merge_recursive to merge all the items in your original array together. And since that function takes a variable number of arguments, making it unwieldy when this number is unknown at compile time, you can use call_user_func_array for extra convenience:

$result = call_user_func_array('array_merge_recursive', $array);

The result will have the "top level" of your input pruned off (logical, since you are merging multiple items into one) but will keep all of the remaining structure.

See it in action.

Upvotes: 13

Related Questions