Reputation: 2654
I have an array of 200 items. I would like to output the array but group the items with a common value. Similar to SQL's GROUP BY method. This should be relatively easy to do but I also need a count for the group items.
Does anyone have an efficient way of doing this? This will happen on every page load so I need it to be fast and scalable.
Could I perhaps dump the results into something like Lucene or SQLite then run a query on that document on each page load?
Upvotes: 13
Views: 38070
Reputation: 47992
Without sample data (a minimal, clear verifiable example) in the question it is difficult to confidently give precise advice on the best way(s) to perform the task. One way is to use temporary grouping keys in the result array. Store an encountered whole row and an appended count
element in the result array if the identifying key hadn't been encountered before. The appended element should have a value of 0
. Then unconditionally increment the count
value. When the loop is finished, if you don't want the grouping keys, you can call array_values()
.
Code: (Demo)
$result = [];
foreach ($array as $row) {
$result[$row['group']] ??= $row + ['count' => 0]; // only save 1st of group with 0 count
++$result[$row['group']]['count']; // increment the count
}
var_export(array_values($result));
Upvotes: 0
Reputation: 1
"$Switches" Array with [3] elements
0
SwitchID 1
name k�
type output
displayAs button
value on
groupname group1
1 Array [6]
2 Array [6]
// this will sort after groupname
$result = array();
$target = count($Switches);
for($i=0;$i<$target;$i++)
{
$groupname = $Switches[$i]["groupname"];
$result[$groupname][] = $Switches[$i];
}
// count amount of groups
$groupCount = count($result);
... or did i miss something?
Upvotes: -1
Reputation: 1436
$aA = array_count_values(array(1,2,3,4,5,1,2,3,4,5,6,1,1,1,2,2));
$aB = array();
foreach($aA as $index=>$aux){
array_push($aB,$index);
}
print_r($aB);
Result:
Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 [5] => 6 )
Upvotes: 2
Reputation: 67177
Just iterate over the array and use another array for the groups. It should be fast enough and is probably faster than the overhead involved when using sqlite or similar.
$groups = array();
foreach ($data as $item) {
$key = $item['key_to_group'];
if (!isset($groups[$key])) {
$groups[$key] = array(
'items' => array($item),
'count' => 1,
);
} else {
$groups[$key]['items'][] = $item;
$groups[$key]['count'] += 1;
}
}
Upvotes: 30
Reputation: 124325
$groups = array();
foreach($items as $item)
$groups[$item['value']][] = $item;
foreach($groups as $value => $items)
echo 'Group ' . $value . ' has ' . count($items) . ' ' . (count($items) == 1 ? 'item' : 'items') . "\n";
Upvotes: 14