PHP - How to merge arrays inside array [closed]
Asked Answered
O

4

70

How to merge n number of array in php. I mean how can I do the job like :
array_merge(from : $result[0], to : $result[count($result)-1])
OR
array_merge_recursive(from: $result[0], to : $result[count($result) -1])


Where $result is an array with multiple arrays inside it like this :

$result = Array(
0 => array(),//associative array
1 => array(),//associative array
2 => array(),//associative array
3 => array()//associative array
)

My Result is :

$result = Array(
    0 => Array(
        "name" => "Name",
        "events" => 1,
        "types" => 2
    ),
    1 => Array(
        "name" => "Name",
        "events" => 1,
        "types" => 3
    ),
    2 => Array(
        "name" => "Name",
        "events" => 1,
        "types" => 4
    ),
    3 => Array(
        "name" => "Name",
        "events" => 2,
        "types" => 2
    ),
    4 => Array(
        "name" => "Name",
        "events" => 3,
        "types" => 2
    )
)

And what I need is

$result = Array(
"name" => "name",
"events" => array(1,2,3),
"types" => array(2,3,4)
)
Outdo answered 11/6, 2013 at 9:52 Comment(4)
There should be no difference. array_merge() + unset() (if needed).Neocene
Instead of a pseudo-code function signature, please describe the data you have and the result you expect.Unclench
I agree with deceze, this question needs a proper minimal reproducible example. This page could receive more/better answers and could be use to close future duplicates -- if this question was actually completed. Right now I find this question to be Unclear.Costume
It doesn't look like ANY of the answers are grouping on the name column and generating subarrays from the remaining columns. I suggest re-closing this messy page to be a signpost for Group row data within a 2d array based on a single column and push unique data into respective subarrays if this page is not outright deleted.Costume
R
202

array_merge can take variable number of arguments, so with a little call_user_func_array trickery you can pass your $result array to it:

$merged = call_user_func_array('array_merge', $result);

This basically run like if you would have typed:

$merged = array_merge($result[0], $result[1], .... $result[n]);

Update:

Now with 5.6, we have the ... operator to unpack arrays to arguments, so you can:

$merged = array_merge(...$result);

And have the same results. *

* The same results as long you have integer keys in the unpacked array, otherwise you'll get an E_RECOVERABLE_ERROR : type 4096 -- Cannot unpack array with string keys error.

Riposte answered 11/6, 2013 at 9:56 Comment(6)
@Riposte , In my case I have two arrays inside an array[ array{array1, array2}], these arrays have same parameters but I need array{[0]=>content of array1, [1]=>content of array2}. What modifications should I do in that case?Trefler
@NikitaDhiman, I don't think i can follow exactly what you need, but from here It seems you'll have to iterate over with foreach and build up the structure you want by "hand". Feels like you just have an extra array around the result you want.Riposte
@Riposte , yes that's exactly the case...an extra array. More of like an array which has the result have two arrays inside it containing the same kind of data. The data within has to be mergedTrefler
@NikitaDhiman in this case, if you know the key you can do $result = $source[0] where the 0 is the key you'll have or if you don't know the hey, you can use reset() to grab the first element of the array (regardless the key) like this: $result = reset($source)Riposte
very good answer but please note that $merged = array_merge(...$result); won't work with array with string keysCircularize
Note that this does not actually produce the result desired in the question…!?Unclench
C
4

I really liked the answer from complex857 but it didn't work for me, because I had numeric keys in my arrays that I needed to preserve.

I used the + operator to preserve the keys (as suggested in PHP array_merge with numerical keys) and used array_reduce to merge the array.

So if you want to merge arrays inside an array while preserving numerical keys you can do it as follows:

<?php
$a = [
    [0 => 'Test 1'],
    [0 => 'Test 2', 2 => 'foo'],
    [1 => 'Bar'],
];    

print_r(array_reduce($a, function ($carry, $item) { return $carry + $item; }, []));
?>

Result:

Array
(
    [0] => Test 1
    [2] => foo
    [1] => Bar
)
Cocoa answered 10/6, 2016 at 12:21 Comment(0)
W
4

If you would like to:

  • check that each param going into array_merge is actually an array
  • specify a particular property within one of the arrays to merge by

You can use this function:

function mergeArrayofArrays($array, $property = null)
{
    return array_reduce(
        (array) $array, // make sure this is an array too, or array_reduce is mad.
        function($carry, $item) use ($property) {

            $mergeOnProperty = (!$property) ?
                    $item :
                    (is_array($item) ? $item[$property] : $item->$property);

            return is_array($mergeOnProperty)
                ? array_merge($carry, $mergeOnProperty)
                : $carry;
    }, array()); // start the carry with empty array
}

Let's see it in action.. here's some data:

Simple structure: Pure array of arrays to merge.

$peopleByTypesSimple = [
    'teachers' => [
            0  => (object) ['name' => 'Ms. Jo', 'hair_color' => 'brown'],
            1  => (object) ['name' => 'Mr. Bob', 'hair_color' => 'red'],
    ],

    'students' => [
            0  => (object) ['name' => 'Joey', 'hair_color' => 'blonde'],
            1  => (object) ['name' => 'Anna', 'hair_color' => 'Strawberry Blonde'],
    ],

    'parents' => [
            0  => (object) ['name' => 'Mr. Howard', 'hair_color' => 'black'],
            1  => (object) ['name' => 'Ms. Wendle', 'hair_color' => 'Auburn'],
    ],
];

Less simple: Array of arrays, but would like to specify the people and ignore the count.

$peopleByTypes = [
    'teachers' => [
        'count' => 2,
        'people' => [
            0  => (object) ['name' => 'Ms. Jo', 'hair_color' => 'brown'],
            1  => (object) ['name' => 'Mr. Bob', 'hair_color' => 'red'],
        ]
    ],

    'students' => [
        'count' => 2,
        'people' => [
            0  => (object) ['name' => 'Joey', 'hair_color' => 'blonde'],
            1  => (object) ['name' => 'Anna', 'hair_color' => 'Strawberry Blonde'],
        ]
    ],

    'parents' => [
        'count' => 2,
        'people' => [
            0  => (object) ['name' => 'Mr. Howard', 'hair_color' => 'black'],
            1  => (object) ['name' => 'Ms. Wendle', 'hair_color' => 'Auburn'],
        ]
    ],
];

Run it

$peopleSimple = mergeArrayofArrays($peopleByTypesSimple);
$people = mergeArrayofArrays($peopleByTypes, 'people');

Results - Both return this:

Array
(
    [0] => stdClass Object
        (
            [name] => Ms. Jo
            [hair_color] => brown
        )

    [1] => stdClass Object
        (
            [name] => Mr. Bob
            [hair_color] => red
        )

    [2] => stdClass Object
        (
            [name] => Joey
            [hair_color] => blonde
        )

    [3] => stdClass Object
        (
            [name] => Anna
            [hair_color] => Strawberry Blonde
        )

    [4] => stdClass Object
        (
            [name] => Mr. Howard
            [hair_color] => black
        )

    [5] => stdClass Object
        (
            [name] => Ms. Wendle
            [hair_color] => Auburn
        )

)

Extra Fun: If you want to single out one property in an array or object, like "name" from an array of people objects(or associate arrays), you can use this function

function getSinglePropFromCollection($propName, $collection, $getter = true)
{
    return (empty($collection)) ? [] : array_map(function($item) use ($propName) {
        return is_array($item) 
            ? $item[$propName] 
            : ($getter) 
                ? $item->{'get' . ucwords($propName)}()
                : $item->{$propName}
    }, $collection);
}

The getter is for possibly protected/private objects.

$namesOnly = getSinglePropFromCollection('name', $peopleResults, false);

returns

Array
(
    [0] => Ms. Jo
    [1] => Mr. Bob
    [2] => Joey
    [3] => Anna
    [4] => Mr. Howard
    [5] => Ms. Wendle
)
Whiteness answered 15/8, 2016 at 20:36 Comment(0)
M
0

Try this

$result = array_merge($array1, $array2);

Or, instead of array_merge, you can use the + op which performs a union:

$array2 + array_fill_keys($array1, '');
Mallina answered 11/6, 2013 at 9:56 Comment(1)
But I need something like this : array_merge($arr_1, $arr_2, ..., $arr_n) because the $result variable may contain n number of associative arrays. Any Suggestion Please.Outdo

© 2022 - 2024 — McMap. All rights reserved.