Home > Software engineering >  Laravel merge 2 o more collections and fusion items
Laravel merge 2 o more collections and fusion items

Time:11-17

I have this collections and need create a new collection with all data.

$data1= new Collection( [
    [
      "date" => "2022-09-07",
      "address" => 1
    ],
     [
      "date" => "2022-08-11",
      "address" => 1
    ]
]);

$data2= new Collection( [
    [
      "date" => "2022-09-10",
      "gender" => 5
    ],
    [
      "date" => "2022-08-11",
      "gender" => 20
    ],
    [
        "date" => "2022-08-06",
        "gender" => 9
    ]
]);

$data3= new Collection( [
    [
      "date" => "2022-09-10",
      "animal" => 10
    ],

]);

Expected result.

^ array:4 [
  0 => array:2 [
    "date" => "2022-09-07"
    "address" => 1
  ]
  1 => array:2 [
    "date" => "2022-08-11"
    "address" => 1,
    "age" => 20,
  ]
  2 => array:2 [
    "date" => "2022-09-10"
    "gender" => 5
    "animal" => 10
  ]
  3 => array:2 [
    "date" => "2022-08-06"
    "gender" => 9
  ]
]

I try "merge" and "union" but result is not correct.

$resultMerge = $data1->merge($data2);
$resultMerge = $resultMerge->merge($data3);

 RESULT:
^ array:6 [
  0 => array:2 [
    "date" => "2022-09-07"
    "address" => 1
  ]
  1 => array:2 [
    "date" => "2022-08-11"
    "address" => 1
  ]
  2 => array:2 [
    "date" => "2022-09-10"
    "gender" => 5
  ]
  3 => array:2 [
    "date" => "2022-08-11"
    "gender" => 20
  ]
  4 => array:2 [
    "date" => "2022-08-06"
    "gender" => 9
  ]
  5 => array:2 [
    "date" => "2022-09-10"
    "animal" => 10
  ]
]

$resultUnion = $data1->union($data2);
$resultUnion = $resultUnion->union($data3);

^ array:3 [
  0 => array:2 [
    "date" => "2022-09-07"
    "address" => 1
  ]
  1 => array:2 [
    "date" => "2022-08-11"
    "address" => 1
  ]
  2 => array:2 [
    "date" => "2022-08-06"
    "gender" => 9
  ]
]

Can you think of any way to obtain the expected result?

CodePudding user response:

You can key the collections by date, then merge them recursively and then just fix the date field:

$result = collect();
$data1
    ->keyBy('date')
    ->mergeRecursive($data2->keyBy('date'))
    ->mergeRecursive($data3->keyBy('date'))
    ->each(function ($item, $key) use ($result) {
        if (is_array($item['date'])) {
            $item['date'] = $key;
        }

        $result->push($item);
    });
dd($result);
  • Related