简体   繁体   中英

Multi Array Counting values of sub-arrays

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM