Reputation: 161
I want to group the data in an array with associative rows. Group should be determined by the type
value and all label_id
values within each group should be formed into a subarray.
Sample input:
$array = [
['type' => 'AAA', 'label_id' => 'A1,35'],
['type' => 'AAA', 'label_id' => 'A2,34'],
['type' => 'BBB', 'label_id' => 'B1,29'],
['type' => 'CCC', 'label_id' => 'C1,20'],
['type' => 'CCC', 'label_id' => 'C2,19'],
['type' => 'CCC', 'label_id' => 'C3,18']
];
The desired result:
[
[
'type' => 'AAA',
'label_id' => [
'A1,35',
'A2,34'
],
[
'type' => 'BBB',
'label_id' => [
'B1,29'
],
],
[
'type' => 'CCC',
'label_id' => [
'C1,20',
'C2,19',
'C3,18',
]
]
]
Upvotes: 14
Views: 39259
Reputation: 1
$args = array(
array('type' => 'AAA', 'label_id' => 'A1,35'),
array('type' => 'AAA', 'label_id' => 'A2,34'),
array('type' => 'BBB', 'label_id' => 'B1,29'),
array('type' => 'CCC', 'label_id' => 'C1,20'),
array('type' => 'CCC', 'label_id' => 'C2,19'),
array('type' => 'CCC', 'label_id' => 'C3,18')
);
$result = [];
foreach ($args as $row) {
$compositeKey = $row['type'];
$result[$compositeKey] = [
'type' => $row['type'],
'label_id' => array_merge($result[$compositeKey]['label_id'] ?? [], [
$row['label_id']
])
];
}
print_r(array_values($result));
Output:
array (
0 =>
array (
'type' => 'AAA',
'label_id' =>
array (
0 => 'A1,35',
1 => 'A2,34',
),
),
1 =>
array (
'type' => 'BBB',
'label_id' =>
array (
0 => 'B1,29',
),
),
2 =>
array (
'type' => 'CCC',
'label_id' =>
array (
0 => 'C1,20',
1 => 'C2,19',
2 => 'C3,18',
),
),
)
Upvotes: -1
Reputation: 47894
This task can be and should be completed with a single loop.
Use the type
values as temporary grouping keys while you store respective row data. The null coalescing assignment operator (??=
) isn't essential (it could be =
and keep overwriting the same value each time), but it endeavors to prevent the re-writing of an identical value over the cached value.
Push label_id
values into the subarray of each respective group. Re-index the array when the loop is finished.
Code: (Demo)
$result = [];
foreach ($array as $row) {
$result[$row['type']]['type'] ??= $row['type'];
$result[$row['type']]['label_id'][] = $row['label_id'];
}
var_export(array_values($result));
For a functional coding style, use array_reduce()
with the same body as the previous snippet. array_reduce()
is appropriate when it is possible that the number of elements in the result may differ from the number of elements in the input array. (Demo)
var_export(
array_values(
array_reduce(
$array,
function($result, $row) {
$result[$row['type']]['type'] ??= $row['type'];
$result[$row['type']]['label_id'][] = $row['label_id'];
return $result;
},
[]
)
)
);
If you want to get funky (unprofessional) with it, you can write a body-less loop with the same functionality/output. (Demo)
$result = [];
foreach ($array as [
'type' => $type,
'label_id' => $id,
'type' => $result[$type]['type'],
'label_id' => $result[$type]['label_id'][]
]);
var_export(array_values($result));
Upvotes: 1
Reputation: 1607
This should do the trick
$args = array
(
array( 'type' => 'AAA', 'label_id' => 'A1,35' ),
array( 'type' => 'AAA', 'label_id' => 'A2,34' ),
array( 'type' => 'BBB', 'label_id' => 'B1,29' ),
array( 'type' => 'CCC', 'label_id' => 'C1,20' ),
array( 'type' => 'CCC', 'label_id' => 'C2,19' ),
array( 'type' => 'CCC', 'label_id' => 'C3,18' )
);
$tmp = array();
foreach($args as $arg)
{
$tmp[$arg['type']][] = $arg['label_id'];
}
$output = array();
foreach($tmp as $type => $labels)
{
$output[] = array(
'type' => $type,
'label_id' => $labels
);
}
var_dump($output);
The output is :
array
0 =>
array
'type' => string 'AAA' (length=3)
'label_id' =>
array
0 => string 'A1,35' (length=5)
1 => string 'A2,34' (length=5)
1 =>
array
'type' => string 'BBB' (length=3)
'label_id' =>
array
0 => string 'B1,29' (length=5)
2 =>
array
'type' => string 'CCC' (length=3)
'label_id' =>
array
0 => string 'C1,20' (length=5)
1 => string 'C2,19' (length=5)
2 => string 'C3,18' (length=5)
Upvotes: 33
Reputation: 19879
<?php
$grouped_types = array();
foreach($types as $type){
$grouped_types[$type['type']][] = $type;
}
?>
Upvotes: 6