-1

I'm need to merge two 2d arrays by their time, size, and type values. This should created grouped data where value_one and value_two elements may exist in the same row. If there aren't two rows to merge together, then I need the missing element to be set to null -- this way all rows will have the same elements/structure.

$array1 = [
    [
        'date' => '2018-06-23',
        'size' => 'L',
        'type' => 'shoes',
        'value_one' => '66',
    ],
    [
        'date' => '2018-06-23',
        'size' => 'XL',
        'type' => 'shirt',
        'value_one' => '43',
    ],
    [
        'date' => '2018-06-23',
        'size' => 'M',
        'type' => 'Bag',
        'value_one' => '23',
    ]
];

And

$array2 = [
    [
        'date' => '2018-06-23',
        'size' => 'L',
        'type' => 'shoes',
        'value_two' => '28',
    ],
    [
        'date' => '2018-06-23',
        'size' => 'XL',
        'type' => 'shirt',
        'value_two' => '56',
    ],
    [
        'date' => '2018-06-23',
        'size' => 'M',
        'type' => 'Bag',
        'value_two' => '14',
    ],
    [
        'date' => '2018-06-23',
        'size' => 'S',
        'type' => 'Cap',
        'value_two' => '29',
    ]
]

Desired result:

[
    [
        'date' => '2018-06-23',
        'size' => 'L',
        'type' => 'shoes',
        'value_one' => '66',
        'value_two' => '28',
    ],
    [
        'date' => '2018-06-23',
        'size' => 'XL',
        'type' => 'shirt',
        'value_one' => '43',
        'value_two' => '56',
    ],
    [
        'date' => '2018-06-23',
        'size' => 'M',
        'type' => 'Bag',
        'value_one' => '23',
        'value_two' => '14',
    ],
    [
        'date' => '2018-06-23',
        'size' => 'S',
        'type' => 'Cap',
        'value_one' => null,
        'value_two' => '29',
    ]
]

I want to solve this case with php, laravel or collection "Laravel" class.

I tried to create the array and merge using array_merge_recursive(), array_merge(), or using this code:

foreach ($d as $k => $v) {
    $new_arr[$v['date']][] = $v;
}
mickmackusa
  • 43,625
  • 12
  • 83
  • 136

5 Answers5

0

try

    //both arrays will be merged including duplicates
    $result = array_merge( $array1, $array2 );
    //duplicate objects will be removed
    $result = array_map("unserialize", array_unique(array_map("serialize", $result)));
    //array is sorted on the bases of id
    sort( $result );
Mayuri Pansuriya
  • 934
  • 6
  • 13
0

For an elegant solution that only needs one loop, use the following:

  1. Hardcode an array of default keys in your desired order.
  2. Merge the arrays and iterate.
  3. Identifying matching data sets by the first three elements in each row.
  4. Depending on whether the composite key has been encountered before, overwrite the default or cached data with the current row.
  5. To remove temporary composite key after looping, call array_values() on the result array.

Code: (Demo)

$defaults = array_fill_keys(['date', 'size', 'type', 'value_one', 'value_two'], null);
$result = [];
foreach (array_merge($array1, $array2) as $row) {
    $compositeKey = implode('_', array_slice($row, 0, 3));
    $result[$compositeKey] = array_merge($result[$compositeKey] ?? $defaults, $row);
}
var_export(array_values($result));
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
-1

You can try this

$Array_final= [];
foreach ($Array_one as $key1 => $value1) {
    foreach ($Array_two as $key2 => $value2) {
        if ($value1['date']==$value2['date']) {
            $Array_final[]=$value2+$value1;
        }
    }
}
tayyab_fareed
  • 559
  • 9
  • 15
-1

You can try this :-

$final = $arr1; // default get all values from first array
foreach ($arr2 as $value) { // loop through second array to match
    $flag = 0;
    foreach ($final as $key => $data) {
        // Check for date, size and type
        if ($data['date']===$value['date'] && $data['size']===$value['size'] && $data['type']===$value['type']) {
            $final[$key]['value_two'] = $value['value_two'];
            $flag = 1;
            break;
        }
    }
    if ($flag === 0) { // If similar not found, then add new one
        array_push($final, $value);
    }
}
print_r($final);

Output :-

Array
(
    [0] => Array
        (
            [date] => 2018-06-23
            [size] => L
            [type] => shoes
            [value_one] => 66
            [value_two] => 28
        )

    [1] => Array
        (
            [date] => 2018-06-23
            [size] => XL
            [type] => shirt
            [value_one] => 43
            [value_two] => 56
        )

    [2] => Array
        (
            [date] => 2018-06-23
            [size] => M
            [type] => Bag
            [value_one] => 23
            [value_two] => 14
        )

    [3] => Array
        (
            [date] => 2018-06-23
            [size] => S
            [type] => Cap
            [value_two] => 29
        )

)

Fiddle link :- https://3v4l.org/fSh1V

Yash Parekh
  • 1,513
  • 2
  • 20
  • 31
-2

try

var result = a1.slice(0);

for (var i = 0 ; i < result.length ; i++){
  for (var j = 0; j < a2.length ; j++){
    if (result[i]. date == a2[j]. date && result[i]. size == a2[j]. size && result[i]. type == a2[j]. type){
      result[i]. value_one = a2[j]. value_one;
      result[i]. value_two = a2[j].value_two;
    }
  };  
};
console.log(result);
Mayuri Pansuriya
  • 934
  • 6
  • 13
  • Please add some explanation to your answer such that others can learn from it. That code does not look like PHP code after all – Nico Haase Sep 25 '22 at 12:06