Home > database >  merge two equal structural multi-arrays with different data
merge two equal structural multi-arrays with different data

Time:03-30

i can't believe that i can't find a solution to this seemingly simple problem, and i tried everything.

i have two multi arrays:

the first one:

Array
(
    [3] => Array
        (
            [1] => Array
                (
                    [approved] => 1
                    [id_note] => 1
                    [surname] => Rawson
                )

            [2] => Array
                (
                    [approved] => 
                    [id_note] => 18
                    [surname] => Vallejo
                )

        )

    [4] => Array
        (
            [1] => Array
                (
                    [school_id] => 1
                )

            [2] => Array
                (
                    [available] => 1
                )

        )

)

the second one has the exact same structure, but with new data:

Array
(
    [3] => Array
        (
            [1] => Array
                (
                    [final_approved] => 1
                    [final_id_note] => 1
                )

            [2] => Array
                (
                    [final_approved] => 
                    [final_id_note] => 19
                )

        )

)

what i need mergin both multi-arrays is this result:

Array
(
    [3] => Array
        (
            [1] => Array
                (
                    [approved] => 1
                    [id_note] => 1
                    [surname] => Rawson
                    [final_approved] => 1
                    [final_id_note] => 1
                )

            [2] => Array
                (
                    [approved] => 
                    [id_note] => 18
                    [surname] => Vallejo
                    [final_approved] => 
                    [final_id_note] => 19
                )

        )

    [4] => Array
        (
            [1] => Array
                (
                    [school_id] => 1
                )

            [2] => Array
                (
                    [available] => 1
                )

        )

)

but i can't get this result with any common php function:

array_merge:

Array
(
    [0] => Array
        (
            [1] => Array
                (
                    [approved] => 1
                    [id_note] => 1
                    [surname] => Rawson
                )

            [2] => Array
                (
                    [approved] => 
                    [id_note] => 18
                    [surname] => Vallejo
                )

        )

    [1] => Array
        (
            [1] => Array
                (
                    [school_id] => 1
                )

            [2] => Array
                (
                    [available] => 1
                )

        )

    [2] => Array
        (
            [1] => Array
                (
                    [final_approved] => 1
                    [final_id_note] => 1
                )

            [2] => Array
                (
                    [final_approved] => 
                    [final_id_note] => 19
                )

        )

)

it replaces with new indexes.

array_push:

Array
(
    [3] => Array
        (
            [1] => Array
                (
                    [approved] => 1
                    [id_note] => 1
                    [surname] => Rawson
                )

            [2] => Array
                (
                    [approved] => 
                    [id_note] => 18
                    [surname] => Vallejo
                )

        )

    [4] => Array
        (
            [1] => Array
                (
                    [school_id] => 1
                )

            [2] => Array
                (
                    [available] => 1
                )

        )

    [5] => Array
        (
            [3] => Array
                (
                    [1] => Array
                        (
                            [final_approved] => 1
                            [final_id_note] => 1
                        )

                    [2] => Array
                        (
                            [final_approved] => 
                            [final_id_note] => 19
                        )

                )

        )

)

it literally pushes in with the second array with new indexes, which is correct of course lol

i guess that the answer is pretty simple, but i already googled and try everything that my newbie ability can.

can anyone give me some advice?

thanks!

CodePudding user response:

There are recursive array functions in PHP. array_merge_recursive, despite the promising name, will not work here, as it will reindex the numeric keys and add overlapping the data to the end.

However, there is array_replace_recursive that does exactly what you want when you have a multidimensional array with significant keys. Here's your data (in a usable format!):

// The base data:

$a_one = [
  3 => [
    1 => [
      'approved' => 1,
      'id_note' => 1,
      'surname' => 'Rawson',
    ],
    2 => [
      'approved' => 0,
      'id_note' => 18,
      'surname' => 'Vallejo',
    ],
  ],
  4 => [
    1 => [
      'school_id' => 1,
    ],
    2 => [
      'available' => 1,
    ],
  ],
];

// Data to be added by matching keys:

$a_two = [
  3 => [
    1 => [
      'final_approved' => 1,
      'final_id_note' => 1,
    ],
    2 => [
      'final_approved' => 0,
      'final_id_note' => 19,
    ],
  ],
];

Then let's mash them together:

$merged = array_replace_recursive($a_one, $a_two);

This results in the following "merged" array:

[
  3 => [
    1 => [
      'approved' => 1,
      'id_note' => 1,
      'surname' => 'Rawson',
      'final_approved' => 1,
      'final_id_note' => 1,
    ],
    2 => [
      'approved' => 0,
      'id_note' => 18,
      'surname' => 'Vallejo',
      'final_approved' => 0,
      'final_id_note' => 19,
    ],
  ],
  4 => [
    1 => [
      'school_id' => 1,
    ],
    2 => [
      'available' => 1,
    ],
  ],
]

In summary, the way this function behaves (from the manual, numbering added):

  1. If a key from the first array exists in the second array, its value will be replaced by the value from the second array.
  2. If the key exists in the second array, and not the first, it will be created in the first array.
  3. If a key only exists in the first array, it will be left as is.

Or in a more compact statement:

key: scalar EXISTS in A, B => REPLACE from B to A
key: scalar EXISTS in B => CREATE in A
key: scalar EXISTS in A => LEAVE in A

Again, the manual says:

When the value in the first array is scalar, it will be replaced by the value in the second array, may it be scalar or array. When the value in the first array and the second array are both arrays, array_replace_recursive() will replace their respective value recursively.

What's important to note here is that array members with matching keys, that are arrays, will not be "replaced" in full. The "replacement" only applies to the final scalar values or "leaves" of the array (per the logic above). The arrays will be "merged", ie. non-matching keys with scalar values will be combined within each "final array" (or "leafy array" for lack of a better term).

N.B. If you're using this function to "merge" more complex arrays, you'll want to double-check that the outcome matches your expectations. I can't remember off the top of my head all the "quirks" that exist in using this function, but I assure you they are there... don't assume that it will create a seamless union of any and all datasets you may throw at it.

  • Related