Reputation: 23
I'm trying to insert high level product review data to SKU records but am stuck with trying to get the average value of duplicated keys.
Array
(
[0] => Array
(
[sku] => 70835
[rating] => 5
)
[1] => Array
(
[sku] => F6W/35
[rating] => 5
)
[2] => Array
(
[sku] => 36865
[rating] => 5
)
[3] => Array
(
[sku] => 36835
[rating] => 5
)
[4] => Array
(
[sku] => F30W/T8/830/POLYLUX
[rating] => 2
)
[5] => Array
(
[sku] => 70835
[rating] => 4
)
)
I would like to get the average rating for the duplicate skus so expected output would be:
Array
(
[0] => Array
(
[sku] => 70835
[rating] => 4.5
)
[1] => Array
(
[sku] => F6W/35
[rating] => 5
)
[2] => Array
(
[sku] => 36865
[rating] => 5
)
[3] => Array
(
[sku] => 36835
[rating] => 5
)
...
)
I have the below loop which is summing the duplicates but I'm struggling to get the average
foreach ($reviews as $val) {
if (!isset($result[$val['sku']]))
{
$result[$val['sku']] = $val;
}
else{
$result[$val['sku']]['rating'] += $val['rating'];
#This will sum the duplicated ratings but I need to divide the sum here by the number of times the 'sku' index was duplicated so in the example 9/2 = 4.5
}
}
thanks in advance!
Upvotes: 2
Views: 260
Reputation: 16997
[akshay@localhost tmp]$ cat test.php
<?php
$array = array (
0 =>
array (
'sku' => '70835',
'rating' => '5',
),
1 =>
array (
'sku' => 'F6W/35',
'rating' => '5',
),
2 =>
array (
'sku' => '36865',
'rating' => '5',
),
3 =>
array (
'sku' => '36835',
'rating' => '5',
),
4 =>
array (
'sku' => 'F30W/T8/830/POLYLUX',
'rating' => '2',
),
5 =>
array (
'sku' => '70835',
'rating' => '4',
),
);
$final=$count=array();
foreach($array as $v)
{
if(isset($final[$v['sku']]))
{
$final[$v['sku']]['rating'] += $v['rating'];
$count[$v['sku']]++;
}else
{
$final[$v['sku']] = $v;
$count[$v['sku']] = 1;
}
}
array_map( function($a, $b) use (&$final){ $final[$a]['rating']/=$b; }, array_keys($count),array_values($count));
unset($count);
// Input
print_r($array);
// Output
print_r( array_values($final));
?>
Output
[akshay@localhost tmp]$ php test.php
Array
(
[0] => Array
(
[sku] => 70835
[rating] => 5
)
[1] => Array
(
[sku] => F6W/35
[rating] => 5
)
[2] => Array
(
[sku] => 36865
[rating] => 5
)
[3] => Array
(
[sku] => 36835
[rating] => 5
)
[4] => Array
(
[sku] => F30W/T8/830/POLYLUX
[rating] => 2
)
[5] => Array
(
[sku] => 70835
[rating] => 4
)
)
Array
(
[0] => Array
(
[sku] => 70835
[rating] => 4.5
)
[1] => Array
(
[sku] => F6W/35
[rating] => 5
)
[2] => Array
(
[sku] => 36865
[rating] => 5
)
[3] => Array
(
[sku] => 36835
[rating] => 5
)
[4] => Array
(
[sku] => F30W/T8/830/POLYLUX
[rating] => 2
)
)
Upvotes: 1
Reputation: 22911
This should work for you:
foreach ($reviews as $val) {
if (!isset($result[$val['sku']]))
{
$result[$val['sku']] = array('rating' => $val['rating'], 'count' => 1);
}
else{
$result[$val['sku']]['rating'] += $val['rating'];
$result[$val['sku']]['count']++;
}
}
foreach ($result as &$val) {
$val['average'] = $val['rating'] / $val['count'];
}
Be aware, if this data is coming from a database, there are much easier ways to do this, by using GROUP BY
statements.
Upvotes: 1
Reputation: 4875
What about adding a count field to your result array...
foreach ($reviews as $val) {
if (!isset($result[$val['sku']]))
{
$result[$val['sku']] = $val;
$result[$val['sku']]["count"] = 1;
}
else{
$result[$val['sku']]['rating'] += $val['rating'];
$result[$val['sku']]["count"] ++;
}
}
foreach($result as $k => $v) {
$result[$k]['avg'] = $v['rating']/$v['count'];
}
Upvotes: 1