I have multi-dimensional array:
$array = array(
array(
"id" => 1,
"value" => 100
),
array(
"id" => 1,
"value" => 200
),
array(
"id" => 1,
"value" => 300
),
array(
"id" => 2,
"value" => 2
),
array(
"id" => 2,
"value" => 5
),
array(
"id" => 3,
"value" => 10.50
),
);
I need to get new multi-dimensional array, like this:
$newArray = array(
array(
"id" => "1",
"sum_of_values" => 600
),
array(
"id" => 2,
"sum_of_values" => 7
),
array(
"id" => 3,
"sum_of_values" => 10.50
),
);
I mean, key [sum_of_values] should counts values in sub-arrays with the same key [id].
I've tried this:
$cnt = count($array);
$finalArray = array();
$tempArray = array();
for($i = 0; $i < $cnt; $i++){
if($array[$i]["id"] == $array[$i++]["id"]){
$search = $array[$i]["id"];
$column = "value";
$sum = array_sum(
array_map(
function($data) use ($column) {
return $data[$column];
},
array_filter(
$array,
function($data) use ($search) {
return fnmatch($search, $data["id"]);
}
)
)
);
$tempArray = array(
"id" => $array[$i]["id"],
"sum_of_values" => $sum
);
$finalArray[] = $tempArray;
} else {
$tempArray = array(
"id" => $array[$i]["id"],
"sum_of_values" => $array[$i]["value"]
);
}
}
And it works, it counts values of sub-arrays with same [id]. But the problem is not returning sub-arrays, key [id] of which doesn't have same examples. In my case - sub-array with [id] = 3 will not return. Also, sub-arrays with [id] = 1 and [id] = 2 will repeat [nn/2] times.
I think, that problem is in using cycle - for ($i = 0; $i < $cnt; $i++)
and condition if ($array[$i]["id"] == $array[$i++]["id"])
, because it looks stupid, but i can't find anything else.
Your function seems too complicated. How about this?
$result = array();
foreach ($array as $item) {
if (!empty($result[$item['id']]))
$result[$item['id']]['sum_of_values'] += $item['value'];
else
$result[$item['id']] = array(
'id' => $item['id'],
'sum_of_values' => $item['value']
);
}
If you print_r($result)
you get:
Array
(
[1] => Array
(
[id] => 1
[sum_of_values] => 600
)
[2] => Array
(
[id] => 2
[sum_of_values] => 7
)
[3] => Array
(
[id] => 3
[sum_of_values] => 10.5
)
)
Just as an alternative: this is a sitter for array_reduce()
:
$totals = array_reduce($array, function($reduction, $current){
$id = $current["id"];
if (empty($reduction[$id])){
$reduction[$id] = ["id"=>$id, "sum_of_values"=>0];
}
$reduction[$id]["sum_of_values"] += $current["value"];
return $reduction;
}, []);
I prefer this sort of approach to generic looping/processing: I think it's a bit cleaner. But mileage varies, obviously.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.