How to merge array of arrays in php?

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
]

[PHP 4, PHP 5, PHP 7, PHP 8]

array_mergeMerge one or more arrays

Description

array_merge[array ...$arrays]: array

If the input arrays have the same string keys, then the later value for that key will overwrite the previous one. If, however, the arrays contain numeric keys, the later value will not overwrite the original value, but will be appended.

Values in the input arrays with numeric keys will be renumbered with incrementing keys starting from zero in the result array.

Parameters

arrays

Variable list of arrays to merge.

Return Values

Returns the resulting array. If called without any arguments, returns an empty array.

Changelog

VersionDescription
7.4.0 This function can now be called without any parameter. Formerly, at least one parameter has been required.

Examples

Example #1 array_merge[] example

The above example will output:

Array
[
    [color] => green
    [0] => 2
    [1] => 4
    [2] => a
    [3] => b
    [shape] => trapezoid
    [4] => 4
]

Example #2 Simple array_merge[] example

Don't forget that numeric keys will be renumbered!

If you want to append array elements from the second array to the first array while not overwriting the elements from the first array and not re-indexing, use the + array union operator:

The keys from the first array will be preserved. If an array key exists in both arrays, then the element from the first array will be used and the matching key's element from the second array will be ignored.

array[5] {
  [0]=>
  string[6] "zero_a"
  [2]=>
  string[5] "two_a"
  [3]=>
  string[7] "three_a"
  [1]=>
  string[5] "one_b"
  [4]=>
  string[6] "four_b"
}

Example #3 array_merge[] with non-array types

The above example will output:

    Array
    [
        [0] => foo
        [1] => bar
    ]

See Also

  • array_merge_recursive[] - Merge one or more arrays recursively
  • array_replace[] - Replaces elements from passed arrays into the first array
  • array_combine[] - Creates an array by using one array for keys and another for its values
  • array operators

Julian Egelstaff

13 years ago

In some situations, the union operator [ + ] might be more useful to you than array_merge.  The array_merge function does not preserve numeric key values.  If you need to preserve the numeric keys, then using + will do that.

ie:



Note the implicit "array_unique" that gets applied as well.  In some situations where your numeric keys matter, this behaviour could be useful, and better than array_merge.

--Julian

ChrisM

9 months ago

I wished to point out that while other comments state that the spread operator should be faster than array_merge, I have actually found the opposite to be true for normal arrays. This is the case in both PHP 7.4 as well as PHP 8.0. The difference should be negligible for most applications, but I wanted to point this out for accuracy.

Below is the code used to test, along with the results:



PHP 7.4:
1.2135608196259 sec for spread
1.1402177810669 sec for array_merge

PHP 8.0:
1.1952061653137 sec for spread
1.099925994873 sec for array_merge

Andreas Hofmann

10 months ago

In addition to the text and Julian Egelstaffs comment regarding to keep the keys preserved with the + operator:
When they say "input arrays with numeric keys will be renumbered" they MEAN it. If you think you are smart and put your numbered keys into strings, this won't help. Strings which contain an integer will also be renumbered! I fell into this trap while merging two arrays with book ISBNs as keys. So let's have this example:



You will get both:

array[4] {
  [0]=>
  string[4] "Mary"
  [1]=>
  string[4] "John"
  [2]=>
  string[4] "Phil"
  [3]=>
  string[7] "Brandon"
}

Use the + operator or array_replace, this will preserve - somewhat - the keys:



You will get both:

array[4] {
  [24]=>
  string[4] "Mary"
  [17]=>
  string[4] "John"
  [67]=>
  string[4] "Phil"
  [33]=>
  string[7] "Brandon"
}

The keys will keep the same, the order will keep the same, but with a little caveat: The keys will be converted to integers.

JoshE

6 months ago

Not to contradict ChrisM's test, but I ran their code example and I got very different results for PHP 8.0.

Testing PHP 8.0.14
1.4955070018768 sec for spread
4.4120140075684 sec for array_merge

How can I merge two arrays in PHP?

PHP array_merge[] Function.
Merge two arrays into one array: $a1=array["red","green"]; $a2=array["blue","yellow"]; ... .
Merge two associative arrays into one array: $a1=array["a"=>"red","b"=>"green"]; $a2=array["c"=>"blue","b"=>"yellow"]; ... .
Using only one array parameter with integer keys: $a=array[3=>"red",4=>"green"];.

How do I merge two arrays together?

The concat[] method concatenates [joins] two or more arrays. The concat[] method returns a new array, containing the joined arrays. The concat[] method does not change the existing arrays.

How do you merge multidimensional arrays?

Merging a multidimensional array is the same as that of a simple array. It takes two arrays as input and merges them. In a multidimensional array, the index will be assigned in increment order and will be appended after the parent array. Now, let's take the example of an employee who has two addresses.

How can I merge two arrays in PHP without duplicates?

You can use the PHP array_unique[] function and PHP array_merge[] function together to merge two arrays into one array without duplicate values in PHP.

Chủ Đề