7

I have following arrays:

$array1 = "
    Array (
        [0] => Array (
                   [0] => Value1
                   [1] => Value2
               )

        [1] => Array (
                   [0] => Value3
                   [1] => Value4
               )

        [2] => Array (
                   [0] => Value5
                   [1] => Value6
               )
        ...
        [999] => Array (
                   [0] => Value7
                   [1] => Value8
               )
    )

and

$array2 = "
    Array (
        [0] => Array (
                   [0] => ValA
                   [1] => ValB
                   [2] => ValC
                   [3] => ValD
               )

        [1] => Array (
                   [0] => ValE
                   [1] => ValF
                   [2] => ValG
                   [3] => ValH
               )

        [2] => Array (
                   [0] => ValI
                   [1] => ValJ
                   [2] => ValK
                   [3] => ValL
               )
        ...
        [999] => Array (
                   [0] => ValM
                   [1] => ValN
                   [2] => ValO
                   [3] => ValP
               )
    )

I would like to merge both arrays so that in the end I have the same structure, number of keys in the first level, but the values would be "joined" in the second level just like we can see in the following result array:

$array3 = "
    Array (
        [0] => Array (
                   [0] => Value1
                   [1] => Value2
                   [2] => ValA
                   [3] => ValB
                   [4] => ValC
                   [5] => ValD
               )

        [1] => Array (
                   [0] => Value3
                   [1] => Value4
                   [2] => ValE
                   [3] => ValF
                   [4] => ValG
                   [5] => ValH
               )

        [2] => Array (
                   [0] => Value5
                   [1] => Value6
                   [2] => ValI
                   [3] => ValJ
                   [4] => ValK
                   [5] => ValL
               )
        ...
        [999] => Array (
                   [0] => Value7
                   [1] => Value8
                   [2] => ValM
                   [3] => ValN
                   [4] => ValO
                   [5] => ValP
               )
    )

I tried with array_merge and array_merge_recursive as showed in this solution: https://stackoverflow.com/a/16541831/3499881, but it didn't work.

  • Do I really have to convert all numeric keys to string or is it somehow also possible with that keys? If this is the only way, could you please show me how I can convert it?

  • Or is the problem caused because in the first array there are 2 keys and in the second 4?

I would appreciate any clue. Many thanks in advance.

Community
  • 1
  • 1
Aloysia de Argenteuil
  • 833
  • 2
  • 11
  • 27

2 Answers2

4

There is an "elegant" way to resolve your issue (it will require, however, that both of your arrays must have same count of items):

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

Check the fiddle.

Answering to your question: array_merge_recursive() will fail because it appends numeric keys, not merging them:

If the input arrays have the same string keys, then the values for these keys are merged together into an array, and this is done recursively, so that if one of the values is an array itself, the function will merge it with a corresponding entry in another array too. If, however, the arrays have the same numeric key, the later value will not overwrite the original value, but will be appended.

Alma Do
  • 37,009
  • 9
  • 76
  • 105
  • Uau! It was a fast answer, thanks! And this is really elegant. And as both arrays will have always the same count of items the solution is better than I would expect. – Aloysia de Argenteuil Jul 03 '14 at 15:11
3

You could loop over $array1, and merge where the key matches in $array2:

$array3 = array();
foreach ($array1 as $key => $a1) {
  if (array_key_exists($key, $array2)) {
    $array3[$key] = array_merge($a1, $array2[$key]);
  } else {
    $array3[$key] = $a1;
  }
}

The only limitation with the above is that if keys exist in $array2, but not in $array1, they won't be added to the array (that's not a problem in your case). Another solution would be to collect all of the keys from both arrays, and then loop over and perform the merge:

$keys = array_unique(array_merge(array_keys($array1), array_keys($array2)));

foreach ($keys as $key) {
  if (array_key_exists($key, $array1) && array_key_exists($key, $array2)) {
    $array3[$key] = array_merge($array1[$key], $array2[$key]);
  } elseif (array_key_exists($key, $array1)) {
    $array3[$key] = $array1[$key];
  } else {
    $array3[$key] = $array2[$key];
  }
}
billyonecan
  • 20,090
  • 8
  • 42
  • 64
  • You can avoid the battery of conditions in the loop if you merge the two (potentially existent) rows and null coalesce each row to an empty array. – mickmackusa Sep 09 '22 at 23:44