Merge rows of two arrays containing objects by first level index
Asked Answered
F

2

0

I am trying to merge the results of two CodeIgniter queries. The trouble is that the two arrays contain rows of objects and array_merge() does not work on objects. How can I merge the two object arrays.

Input:

$array1 = [
    (object) [
        'trainerid' => 1,
        'firstname' => 'abc',
        'location' => 'area',
        'photo' => 'abc.jpg',
        'role' => 'user',
        'city' => 'bangalore',
    ],
    (object) [
        'trainerid' => 2,
        'firstname' => 'abcd',
        'location' => 'area',
        'photo' => 'abcd.jpg',
        'role' => 'user',
        'city' => 'bangalore',
    ],
];

$array2 = [
    (object) [
        'rating' => 3.0000,
        'users' => 0,
        'review' => 0
    ],
    (object) [
        'rating' => 4.0000,
        'users' => 4,
        'review' => 5
    ]
];

Desired output:

array (
  0 => 
  (object) array(
     'trainerid' => 1,
     'firstname' => 'abc',
     'location' => 'area',
     'photo' => 'abc.jpg',
     'role' => 'user',
     'city' => 'bangalore',
     'rating' => 3.0,
     'users' => 0,
     'review' => 0,
  ),
  1 => 
  (object) array(
     'trainerid' => 2,
     'firstname' => 'abcd',
     'location' => 'area',
     'photo' => 'abcd.jpg',
     'role' => 'user',
     'city' => 'bangalore',
     'rating' => 4.0,
     'users' => 4,
     'review' => 5,
  ),
)
Faubert answered 26/11, 2015 at 7:48 Comment(0)
K
1

You've made a relatively basic task much harder to do by using CodeIgniter's ->result() instead of ->result_array(). If you had arrays of arrays, then you could just use array_map('array_merge', $array1, $array2), but that will not work with your object arrays.

Instead, you'll need to call get_object_vars() on each object (and you are going to be iterating multiple objects inside the outer array_map().

Essentially, this task is a matter of iterating both arrays simultaneously, casting each pair of objects to array type, then merging the arrays, then casting the merged array back to object type.

The following snippet is designed with the flexibility to process 2 or more object arrays.

Code: (Demo)

var_export(
    array_map(
        fn(...$objs) => (object) array_merge(...array_map('get_object_vars', $objs)),
        $array1,
        $array2
    )
);

The above can be written a little more concisely when only two object arrays are being merged. (Demo)

var_export(
    array_map(
        fn($obj1, $obj2) => (object) array_merge((array) $obj1, (array) $obj2),
        $array1,
        $array2
    )
);

A classic nested foreach approach can be used to avoid casting and recasting data types while merging. array_merge() and array_merge_recursive() cannot (currently) be used to merge objects together -- their properties must be individually defined in the receiving object. (Demo)

$result = [];
foreach ($array1 as $i => $obj1) {
    $result[$i] = $obj1;
    foreach ($array2[$i] as $k => $v) {
        $result[$i]->$k = $v;
    }
}
var_export($result);

Output from any of the above snippets:

array (
  0 => 
  (object) array(
     'trainerid' => 1,
     'firstname' => 'abc',
     'location' => 'area',
     'photo' => 'abc.jpg',
     'role' => 'user',
     'city' => 'bangalore',
     'rating' => 3.0,
     'users' => 0,
     'review' => 0,
  ),
  1 => 
  (object) array(
     'trainerid' => 2,
     'firstname' => 'abcd',
     'location' => 'area',
     'photo' => 'abcd.jpg',
     'role' => 'user',
     'city' => 'bangalore',
     'rating' => 4.0,
     'users' => 4,
     'review' => 5,
  ),
)
Kreegar answered 30/8, 2022 at 10:11 Comment(0)
J
0

You need to use array_map along with the array_merge like as

print_r(array_map('array_merge', $arr1, $arr2));
Jepson answered 26/11, 2015 at 8:48 Comment(1)
This answer is provably incorrect.Kreegar

© 2022 - 2024 — McMap. All rights reserved.