I'm need to merge an array of rows into groups and use the lowest id in each group as the first level key. Within each group, all encountered ids (excluding the lowest) should be gathered in a subarray called mergedWith
.
Sample input:
[
1649 => ["firstName" => "jack", "lastName" => "straw"],
1650 => ["firstName" => "jack", "lastName" => "straw"],
1651 => ["firstName" => "jack", "lastName" => "straw"],
1652 => ["firstName" => "jack", "lastName" => "straw"],
]
My desired result:
[
1649 => [
"firstName" => "jack"
"lastName" => "straw"
"mergedWith" => [1650, 1651, 1652]
]
]
I have a loop running that can pull out duplicates and find the lowest ID in the group, but not sure of the right way to collapse them into one.
I've shown the desired results of a search that has identified id's with duplicate entries in those particular fields. I just want to further refine it to not delete, but add a field on the end of each group that says ["mergedWith" => [1650, 1651, 1652]]
One way to do it is to group by first name and last name, and then reverse the grouping to get a single id. krsort
the input beforehand to make sure you get the lowest id.
krsort($input);
//group
foreach ($input as $id => $person) {
// overwrite the id each time, but since the input is sorted by id in descending order,
// the last one will be the lowest id
$names[$person['lastName']][$person['firstName']] = $id;
}
// ungroup to get the result
foreach ($names as $lastName => $firstNames) {
foreach ($firstNames as $firstName => $id) {
$result[$id] = ['firstName' => $firstName, 'lastName' => $lastName];
}
}
Edit: not too much different based on your updated question. Just keep all the ids instead of a single one.
krsort($input);
foreach ($input as $id => $person) {
// append instead of overwrite ↓
$names[$person['lastName']][$person['firstName']][] = $id;
}
foreach ($names as $lastName => $firstNames) {
foreach ($firstNames as $firstName => $ids) {
// $ids is already in descending order based on the initial krsort
$id = array_pop($ids); // removes the last (lowest) id and returns it
$result[$id] = [
'firstName' => $firstName,
'lastName' => $lastName,
'merged_with' => implode(',', $ids)
];
}
}