Reputation: 7923
How can a group a collection based on their values? For example this one:
Collection {#250 ▼
#items: array:4 [▼
"CASSETE_1" => "500"
"CASSETE_2" => "500"
"CASSETE_3" => "100"
"CASSETE_4" => "100"
]
}
I need to group it and get a result like this:
Collection {#250 ▼
#items: array:4 [▼
"CASSETE_1 / CASSETE_2" => "500"
"CASSETE_3 / CASSETE_4" => "100"
]
}
Is that possible?
I used unique()
but the result is:
Collection {#251 ▼
#items: array:2 [▼
"CASSETE_1" => "500"
"CASSETE_3" => "100"
]
}
Upvotes: 0
Views: 834
Reputation: 47874
This can be accomplished wholly with Laravel's collection methods. Use mapToGroups()
to group by amounts, then call mapWithKeys()
with implode()
to form the desired associative structure with delimited keys.
Code: (PHPize Demo)
$collection = collect([
"CASSETE_1" => "500",
"CASSETE_2" => "500",
"CASSETE_3" => "100",
"CASSETE_4" => "100",
]);
var_export(
$collection->mapToGroups(fn($amt, $cassete) => [$amt => $cassete])
->mapWithKeys(fn($cassetes, $amt) => [$cassetes->implode(' / ') => $amt])
->toArray()
);
Output:
array (
'CASSETE_1 / CASSETE_2' => 500,
'CASSETE_3 / CASSETE_4' => 100,
)
Upvotes: 0
Reputation: 2593
Try this below ( convert the collection into Array first ) :
$input = [
"CASSETE_1" => "500",
"CASSETE_2" => "500",
"CASSETE_3" => "100",
"CASSETE_4" => "100",
];
$values = array_unique(array_values($input));
// output results
$output =[];
foreach ($values as $v) {
$index = implode(", ", array_keys($input, $v));
$output[$index] = $v;
}
print_r($output);
The output should be:
Array ( [CASSETE_1, CASSETE_2] => 500, [CASSETE_3, CASSETE_4] => 100 )
You should be able to construct the index string that you want by changing the ',' with the character that you need.
Upvotes: 0
Reputation: 15464
There is no native way to do that , you need to make custom function. This is what I did
1 Convert collection to array
2 Flip it
3 Filter by value and join them by /
4 flip it again
$arr=array("CASSETE_1" => "500",
"CASSETE_2" => "500",
"CASSETE_3" => "100",
"CASSETE_4" => "100");
$result = array();
foreach (array_flip($arr) as $k=>$v) {
$result[$k] = implode("/",array_keys(array_filter($arr, function($elem) use($k){
return $elem == $k;
})));
}
echo "<pre>";
print_r(array_flip($result));
output
Array
(
[CASSETE_1/CASSETE_2] => 500
[CASSETE_3/CASSETE_4] => 100
)
Upvotes: 1