Hướng dẫn merge multidimensional array php

i have a problem to merge this array, I want to merge this array bellow

    Array
    [
       [0] => Array
           [
               [image] => logo.jpg
               [name] => data
               [server] => Mirani Rahmawati
               [6] => 5
           ]

       [1] => Array
           [
               [image] => logo.jpg
               [name] => data
               [server] => Mirani Rahmawati
               [5] => 150
           ]
       ]
   

and the expected result will be like this

Array
[
    [0] => Array
        [
            [image] => logo.jpg
            [name] => data
            [server] => Mirani Rahmawati
            [6] => 5
            [5] => 150
        ]

]

without changing the key..

Thankyou.

asked Sep 28, 2021 at 2:53

You can use Array Operators + to do that. You can check my below demo:


The result will be:

Array
[
    [image] => logo.jpg
    [name] => data
    [server] => Mirani Rahmawati
    [6] => 5
    [5] => 150
]

You can find out more at //www.php.net/manual/en/language.operators.array.php

answered Sep 28, 2021 at 3:06

TartarusTartarus

2,4881 gold badge9 silver badges19 bronze badges

1



The above example will output:

Array
[
    [color] => Array
        [
            [favorite] => Array
                [
                    [0] => red
                    [1] => green
                ]

            [0] => blue
        ]

    [0] => 5
    [1] => 10
]

See Also

  • array_merge[] - Merge one or more arrays
  • array_replace_recursive[] - Replaces elements from passed arrays into the first array recursively

gabriel dot sobrinho at gmail dot com

13 years ago

I refactored the Daniel's function and I got it:



This fix the E_NOTICE when the the first array doesn't have the key and the second array have a value which is a array.

thomas at n-o-s-p-a-m dot thoftware dot de

14 years ago

This is a simple, three line approach.

Short description: If one of the Arguments isn't an Array, first Argument is returned. If an Element is an Array in both Arrays, Arrays are merged recursively, otherwise the element in $ins will overwrite the element in $arr [regardless if key is numeric or not]. This also applys to Arrays in $arr, if the Element is scalar in $ins [in difference to the previous approach].

  function array_insert[$arr,$ins] {
    # Loop through all Elements in $ins:
    if [is_array[$arr] && is_array[$ins]] foreach [$ins as $k => $v] {
      # Key exists in $arr and both Elemente are Arrays: Merge recursively.
      if [isset[$arr[$k]] && is_array[$v] && is_array[$arr[$k]]] $arr[$k] = array_insert[$arr[$k],$v];
      # Place more Conditions here [see below]
      # ...
      # Otherwise replace Element in $arr with Element in $ins:
      else $arr[$k] = $v;
    }
    # Return merged Arrays:
    return[$arr];
  }

In Addition to felix dot ospald at gmx dot de in my opinion there is no need to compare keys with type-casting, as a key always is changed into an integer if it could be an integer. Just try

$a = array['1'=>'1'];
echo gettype[key[$a]];

It will echo 'integer'. So for having Integer-Keys simply appended instead of replaced, add the Line:

  elseif [is_int[$k]] $arr[] = $v;

A Condition I used is:

  elseif [is_null[$v]] unset[$arr[$k]];

So a NULL-Value in $ins will unset the correspondig Element in $arr [which is different to setting it to NULL!]. This may be another Addition to felix dot ospald at gmx dot de: The absolute correct way to check for a Key existing in an Array is using array_key_exists[] [not needed in the current context, as isset[] is combined with is_array[]]. array_key_exists[] will return TRUE even if the Value of the Element is NULL.

And the last one: If you want to use this approach for more than 2 Arrays, simply use this:

  function array_insert_mult[$arr] {
    # More than 1 Argument: Append all Arguments.
    if [func_num_args[] > 1] foreach [array_slice[func_get_args[],1] as $ins] $arr = array_insert[$arr,$ins];
    # Return merged Arrays:
    return[$arr];
  }

And if you worry about maintaining References: Simply use $ins[$k] instead of $v when assigning a Value/using a Value as Argument.

martyniuk dot vasyl at gmail dot com

10 years ago

This is my version of array_merge_recursive without overwriting numeric keys:

remy dot damour at -please-no-spam-laposte dot net

13 years ago

If what you want is merge all values of your array that are arrays themselves to get a resulting array of depth one, then you're more looking for array_flatten function.

Unfortunately I did not find such native function in php, here is the one I wrote:

fantomx1 at gmail dot com

6 years ago

I little bit improved daniel's and gabriel's contribution to behave more like original array_merge function to append numeric keys instead of overwriting them and added usefull option of specifying which elements to merge as you more often than not need to merge only specific part of array tree, and some parts of array just need  to let overwrite previous. By specifying helper element mergeWithParent=true, that section of array  will be merged, otherwise latter array part will override former. First level of array behave as classic array_merge.

        function array_merge_recursive_distinct [ array &$array1, array &$array2 ]
    {
        static $level=0;
        $merged = [];
        if [!empty[$array2["mergeWithParent"]] || $level == 0] {
            $merged = $array1;
        }

        foreach [ $array2 as $key => &$value ]
        {
            if [is_numeric[$key]] {
                $merged [] = $value;
            } else {
                $merged[$key] = $value;
            }

            if [ is_array [ $value ] && isset [ $array1 [$key] ] && is_array [ $array1 [$key] ]
            ] {
                $level++;
                $merged [$key] = array_merge_recursive_distinct[$array1 [$key], $value];
                $level--;
            }
        }
        unset[$merged["mergeWithParent"]];
        return $merged;
    }

daniel at danielsmedegaardbuus dot dk

13 years ago

walf

11 years ago

There are a lot of examples here for recursion that are meant to behave more like array_merge[] but they don't get it quite right or are fairly customised. I think this version is most similar, takes more than 2 arguments and can be renamed in one place:



gives:

array[7] {              array[7] {              array[7] {
  int[1]                  int[1]                  int[1]
  ["foo"]=>               ["foo"]=>               ["foo"]=>
  array[1] {              array[1] {              array[2] {
    [0]=>                   [0]=>                   [0]=>
    int[8]                  int[8]                  int[2]
  }                       }                         [1]=>
  ["bar"]=>               ["bar"]=>                 int[8]
  int[9]                  int[9]                  }
  ["x"]=>                 ["x"]=>                 ["bar"]=>
  int[5]                  int[5]                  array[2] {
  ["z"]=>                 ["z"]=>                   [0]=>
  array[1] {              array[3] {                int[4]
    ["m"]=>                 [0]=>                   [1]=>
    string[4] "ciao"        int[6]                  int[9]
  }                         ["m"]=>               }
  [1]=>                     string[4] "ciao"      ["x"]=>
  int[7]                    [1]=>                 int[5]
  ["y"]=>                   int[11]               ["z"]=>
  int[10]                 }                       array[3] {
}                         [1]=>                     [0]=>
                          int[7]                    int[6]
                          ["y"]=>                   ["m"]=>
                          int[10]                   array[3] {
                        }                             [0]=>
                                                      string[2] "hi"
                                                      [1]=>
                                                      string[3] "bye"
                                                      [2]=>
                                                      string[4] "ciao"
                                                    }
                                                    [1]=>
                                                    int[11]
                                                  }
                                                  [1]=>
                                                  int[7]
                                                  ["y"]=>
                                                  int[10]
                                                }

jonnybergstrom at googles mail domain dot comm

13 years ago

This function didn't work for me - or it didn't do what I thought it would. So I wrote the below function, which merges two arrays, and returns the resulting array. The base array is the left one [$a1], and if a key is set in both arrays, the right value has precedence. If a value in the left one is an array and also an array in the right one, the function calls itself [recursion]. If the left one is an array and the right one exists but is not an array, then the right non-array-value will be used.

*Any key only appearing in the right one will be ignored*
- as I didn't need values appearing only in the right in my implementation, but if you want that you could make some fast fix.

function array_merge_recursive_leftsource[&$a1, &$a2] {
    $newArray = array[];
    foreach [$a1 as $key => $v] {
        if [!isset[$a2[$key]]] {
            $newArray[$key] = $v;
            continue;
        }

        if [is_array[$v]] {
            if [!is_array[$a2[$key]]] {
                $newArray[$key] = $a2[$key];
                continue;
            }
            $newArray[$key] = array_merge_recursive_leftsource[$a1[$key], $a2[$key]];
            continue;
        }

        $newArray[$key] = $a2[$key];
    }
    return $newArray;
}

spambegone at cratemedia dot com

14 years ago

I've tried these array_merge_recursive functions without much success. Maybe it's just me but they don't seem to actually go more than one level deep? As with all things, its usually easier to write your own, which I did and it seems to work just the way I wanted. Anyways, my function hasn't been tested extensively, but it's a simple function, so in hopes that this might be useful to someone else I'm sharing.

Also, the PHP function array_merge_recursive[] didn't work for my purposes because it didn't overwrite the values like I needed it to. You know how it works, it just turns it into an array with multiple values... not helpful if your code is expecting one string.

function array_merge_recursive_unique[$array1, $array2] {

        // STRATEGY
    /*
    Merge array1 and array2, overwriting 1st array values with 2nd array
    values where they overlap. Use array1 as the base array and then add
    in values from array2 as they exist.

        Walk through each value in array2 and see if a value corresponds
    in array1. If it does, overwrite with second array value. If it's an
    array, recursively execute this function and return the value. If it's
    a string, overwrite the value from array1 with the value from array2.

        If a value exists in array2 that is not found in array1, add it to array1.
    */

    // LOOP THROUGH $array2
    foreach[$array2 AS $k => $v] {

                // CHECK IF VALUE EXISTS IN $array1
        if[!empty[$array1[$k]]] {
            // IF VALUE EXISTS CHECK IF IT'S AN ARRAY OR A STRING
            if[!is_array[$array2[$k]]] {
                // OVERWRITE IF IT'S A STRING
                $array1[$k]=$array2[$k];
            } else {
                // RECURSE IF IT'S AN ARRAY
                $array1[$k] = array_merge_recursive_unique[$array1[$k], $array2[$k]];
            }
        } else {
            // IF VALUE DOESN'T EXIST IN $array1 USE $array2 VALUE
            $array1[$k]=$v;
        }
    }
    unset[$k, $v];

            return $array1;
}

brian at vermonster dot com

18 years ago

Here is a fairly simple function that replaces while recursing.



Examples:


Result 1 is:
Array
[
    [liquids] => Array
        [
            [water] => hot
            [beer] => warm
            [milk] => wet
        ]
]

Result 2 is:
Array
[
    [liquids] => Array
        [
            [water] => Array
                [
                    [0] => cold
                    [1] => fizzy
                    [2] => clean
                ]

            [milk] => wet
            [beer] => warm
        ]
]

andyidol at gmail dot com

11 years ago

Here's my function to recursively merge two arrays with overwrites. Nice for merging configurations.

mark dot roduner at gmail dot com

12 years ago

robert dot schlak at alcatel-lucent dot com

10 years ago

The presence of NULLs; here is an example of the issue and a fix. Although it may not be apparent, if using array_merge_recursive in a loop to combine results from a database query or some other function, you can corrupt your result when NULLs are present in the data. I discovered this when migrating from an Oracle DB to a MySQL DB. I had to match the array structure returned from the PHP function calling the DB and got bit. The array_walk call fixed this for me.
This is a simple example that lacks any DB calls and looping. Assume your array had the DB column names [first, last, and age] and you needed to combine the data in a multi-dimensional array in which the column name is an array key with all rows beneath it. The corruption occurs in $a3. If using element position 2, one could create the fictitious 'pete johnson' because of the collapsing of elements.

miniscalope at gmail dot com

13 years ago

I would merge 2 arrays but keep the values unique in the result array.
I hope this will help...

paha at paha dot hu

15 years ago

In this version the values are overwritten only if they are not an array.  If the value is an array, its elements will be merged/overwritten:

// array_merge_recursive which override value with next value.
// based on: //www.php.net/manual/hu/function.array-merge-recursive.php 09-Dec-2006 03:38
function array_merge_recursive_unique[$array0, $array1]
{
    $arrays = func_get_args[];
    $remains = $arrays;

    // We walk through each arrays and put value in the results [without
    // considering previous value].
    $result = array[];

    // loop available array
    foreach[$arrays as $array] {

        // The first remaining array is $array. We are processing it. So
        // we remove it from remaing arrays.
        array_shift[$remains];

        // We don't care non array param, like array_merge since PHP 5.0.
        if[is_array[$array]] {
            // Loop values
            foreach[$array as $key => $value] {
                if[is_array[$value]] {
                    // we gather all remaining arrays that have such key available
                    $args = array[];
                    foreach[$remains as $remain] {
                        if[array_key_exists[$key, $remain]] {
                            array_push[$args, $remain[$key]];
                        }
                    }

                    if[count[$args] > 2] {
                        // put the recursion
                        $result[$key] = call_user_func_array[__FUNCTION__, $args];
                    } else {
                        foreach[$value as $vkey => $vval] {
                            $result[$key][$vkey] = $vval;
                        }
                    }
                } else {
                    // simply put the value
                    $result[$key] = $value;
                }
            }
        }
    }
    return $result;
}

phil dot kemmeter at gmail dot com

13 years ago

I've edit this version even a little bit more, so that the function does not override any values, but inserts them at a free key in the array:

function my_array_merge [$arr,$ins] {
    if[is_array[$arr]]
    {
        if[is_array[$ins]] foreach[$ins as $k=>$v]
        {
            if[isset[$arr[$k]]&&is_array[$v]&&is_array[$arr[$k]]]
            {
                $arr[$k] = my_array_merge[$arr[$k],$v];
            }
            else {
                // This is the new loop :]
                while [isset[$arr[$k]]]
                    $k++;
                $arr[$k] = $v;
            }
        }
    }
    elseif[!is_array[$arr]&&[strlen[$arr]==0||$arr==0]]
    {
        $arr=$ins;
    }
    return[$arr];
}

Example:

$array1 = array[
    100 => array[30],
    200 => array[20, 30]
];

$array2 = array[
    100 => array[40],
    201 => array[60, 30]
];

print_r[my_array_merge[$array1,$array2]];

Output with array_merge_recursive:
Array
[
    [0] => Array
        [
            [0] => 30
        ]

    [1] => Array
        [
            [0] => 20
            [1] => 30
        ]

    [2] => Array
        [
            [0] => 40
        ]

]
This is not the result, I expect from a MERGE-Routine...

Output with the current function:

Array
[
    [100] => Array
        [
            [0] => 30
            [1] => 40
        ]

    [200] => Array
        [
            [0] => 20
            [1] => 30
        ]

]

This is what I want :]

andrew at indigo - sphere dot co dot uk

2 years ago

An alternative solution where this function does not produce the desired output: Pass a custom recursive function to array_reduce[]:

For example [Using PHP 7 capabilities to create recursive anonymous function]:

Chủ Đề