对两个数组进行分组和求和 [英] Group and sum items from two arrays

查看:81
本文介绍了对两个数组进行分组和求和的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在遍历两个存储过程的结果集,根据两个过程中的字段获取最终结果。

I'm looping through the result sets of two stored procedures, getting the final results based on fields within both procedures.

下面是两个结果集:

-获取所有 $ customers ,无论是否包含数据:

-Get all the $customers with or without data:

| id |   name  | parentID | calls | duration |  type | 
+----+---------+----------+-------+----------+-------+
|  8 | Telekom |    80    |  100  |   3000   | 01-02 |  
|  8 | Telekom |    80    |   10  |    700   |   080 |
|  8 | Telekom |    80    |    5  |    100   |    05 |
| 16 |  Orange |     7    |   50  |   2200   |    03 |
| 16 |  Orange |     7    | NULL  |   NULL   |  NULL |
|  9 | Verizon |     2    | NULL  |   NULL   |  NULL |  
| 18 |   T&T   |    108   |   30  |   1200   |    04 |  
| 20 |  Sprint |    33    |  120  |   4000   |    09 | 
| 20 |  Sprint |    33    |   60  |   3500   | 01-02 |
| 17 | CellCom |    99    | NULL  |   NULL   |  NULL | 
|  1 | T-Mobile|    14    |   85  |   2600   |   087 | 
|  1 | T-Mobile|    14    |    2  |     30   |    07 |
| 34 | US-Cell |    27    |  240  |   1700   |   084 | 

-使用数据获取所有 $ subcustomers

| id |      name     | parentID | calls | duration |  type | 
+----+---------------+----------+-------+----------+-------+
| 44 |     CallMe    |     8    |   20  |   400    | 01-02 |
| 44 |     CallMe    |     8    |    5  |    20    |   080 |
| 44 |     CallMe    |     8    |   15  |   200    |   087 |
| 72 |    DialNow    |    16    |  100  |  2000    |    03 |
| 72 |    DialNow    |    16    |    5  |   100    |    04 |
| 13 |    Online4U   |     9    |   10  |    25    |    05 |
| 22 | TeleSolutions |     9    |   30  |   200    |    05 |
|  4 |    FonezInc   |     9    |    5  |     5    |   084 |
| 10 |      Digi     |    20    |  100  |  4000    |    09 |
| 11 |    Vodafone   |    20    |   40  |  2400    |    08 |

所需结果应如下:

-根据正确的类型,将子客户的所有呼叫/持续时间添加到客户的呼叫/持续时间(如果subcustomer.parentID = customer.id),否则向客户显示数据。

-如果客户没有呼叫/类型(NULL),并且子客户带有呼叫,则将其添加到客户中。

-如果子客户具有不同类型的呼叫,请将这些呼叫也添加到客户中

-类型是动态的,我们现在不知道将有多少种类型< br>
如下所示:

-Add all calls/duration of subcustomers to the customers ones (if subcustomer.parentID = customer.id), against the correct type, otherwise show customers with data.
-If a customer has no calls/type (NULL) and has subcustomers with calls, add these to the customer.
-If a subcustomer has different types of calls, add these to the customer also
-The types are dynamic, we don't now what/how many types there will be
Like below:

| id |   name  | parentID | calls | duration |  type | 
+----+---------+----------+-------+----------+-------+
|  8 | Telekom |    80    |  120  |    3400  | 01-02 |
|  8 | Telekom |    80    |   15  |     720  |   080 |
|  8 | Telekom |    80    |    5  |     100  |    05 |
|  8 | Telekom |    80    |   15  |     200  |   087 |
| 16 |  Orange |     7    |  150  |    4200  |    03 |
| 16 |  Orange |     7    |    5  |     100  |    04 |
|  9 | Verizon |     2    |   40  |     225  |    05 |
|  9 | Verizon |     2    |    5  |       5  |   084 |
| 18 |   T&T   |    108   |   30  |    1200  |    04 |
| 20 |  Sprint |    33    |  220  |    4000  |    09 |
| 20 |  Sprint |    33    |   60  |    3500  | 01-02 |
| 20 |  Sprint |    33    |   40  |    2400  |    08 |
|  1 | T-Mobile|    14    |   85  |   2600   |   087 | 
|  1 | T-Mobile|    14    |    2  |     30   |    07 |
| 34 | US-Cell |    27    |  240  |   1700   |   084 |

一个想法是将个子客户和<临时关联数组中的code> customers ,其中 parentID ID 作为键。之后,我们可以构建结果。



输入1 这里有一些临时 subcustomers 数组的虚拟数据

该数组包含按parentId(第一级)和调用类型(第二级)分组的调用。它具有以下结构:

An idea is to group subcustomers and customers in temporary associative arrays with parentID and ID as keys. After that we can built the result.

Input 1: Here's some dummy data for the temporary subcustomers array.
This array contains calls grouped by parentId (first level) and call type (second level). It has the following structure:

[parentID] => Array
    (
        [type] => Array  // e.g. type = 03
            (
                [calls] => value  //calls of type 03
                [duration] => value  //duration of type 03
            )
        [type] => Array //e.g. type = 087
            (
                [calls] => value  //calls of type 087
                [duration] => value  //duration of type 087
            )
         ...
    )

下面是创建临时文件的代码。子客户数组:

Below is the code that creates the temp. subcustomers array:

$tempS = array();

foreach($subcustomers as $subcustomer) {
    $parentId = $subcustomer['parentID'];
    $calls    = $subcustomer['calls'];
    $type     = $subcustomer['type'];
    $duration = $subcustomer['duration'];

    //if id/type is insered yet
    if(array_key_exists($parentId, $tempS) && array_key_exists($type, $tempS[$parentId])) {
        $tempS[$parentId][$type]['calls'] += $calls;
        $tempS[$parentId][$type]['duration'] += $duration;
    } else {
        $tempS[$parentId][$type]['calls'] = $calls;
        $tempS[$parentId][$type]['duration'] = $duration;
    }    
}



输入2 此处为临时数据客户阵列。该数组的结构如下:


Input 2: Here's dummy data for the temp. customers array. The structure of this array is as follows:

[id] => Array    
    (
        [name] => 'Telekom'
        [parentID] => 80
        [calls] => Array
            (
                [type] => // e.g. calls of type 01-02
                [type] => // e.g. calls of type 05
            )
        [duration] => Array
            (
                [type] => //duration of type 01-02
                [type] => //duration of type 05
            )
    )

以下是临时代码。客户数组:

Here's the code for the temp. customers array:

$tempC = array();

foreach($customers as $customer) {
    $id       = $customer['id'];
    $name     = $customer['name'];
    $parentId = $customer['parentID'];
    $calls    = $customer['calls'];
    $type     = $customer['type'];
    $duration = $customer['duration'];

    //if id/type is insered yet
    if(array_key_exists($id, $tempC) && array_key_exists($type, $tempC[$id])) {
            $tempC[$id]['calls'][$type] += $calls;
            $tempC[$id]['duration'][$type] += $duration;
        } else {
            //if subcustomer has calls of that type
            if(array_key_exists($customerId, $tempS) && array_key_exists($type, $tempS[$customerId])) {
                $tempC[$id]['calls'][$type] = $tempS[$id][$type] + $calls;
                $tempC[$id]['duration'][$type] = $tempS[$id][$type] + $duration;
            } else {
                $tempC[$id]['calls'][$type] = $calls;
                $tempC[$id]['duration'][$type] = $duration;
            }
        $tempC[$id]['name'] = $name;
        $tempC[$id]['parentID'] = $parentId;
    }
}

具有这两个温度。数组我们应该计算结果数组。

Having these two temp. arrays we should compute the result array.

输出应具有如下相同的结构:

The output should have the same structure as follows:

Array
(
    [0] => Array  //indexes should be incremented, starting from 0
        (
            [name] => Telekom
            [label] => 01-02  //label = type
            [count] => 120
            [mins] => 3400
            [customerid] => 8
        )

    [1] => Array
        (
            [name] => Telekom
            [label] => 080
            [count] => 15
            [mins] => 720  // mins = (duration / 60)
            [customerid] => 8
        )
    [2] => Array
        (
            [name] => Telekom
            [label] => 05
            [count] => 5
            [mins] => 100
            [customerid] => 8
        )
    [3] => Array
        (
            [name] => Telekom
            [label] => 087
            [count] => 15
            [mins] => 200
            [customerid] => 8
        )


    [4] => Array
        (
            [name] => Orange
            [label] => 03
            [count] => 150
            [mins] => 4200
            [customerid] => 16
        )

    [5] => Array
        (
            [name] => Orange
            [label] => 04
            [count] => 5
            [mins] => 100
            [customerid] => 16
        )
    ....

)

我尝试过:

$result = array();

foreach($tempC as $id => $customer) {

        $type = key($customer['calls']); // ??
        $calls = 0;
        $duration = 0;

        //sums calls of customer
        if(array_key_exists('calls', $customer) && array_key_exists($type, $customer['calls'])) {
            $calls += $customer['calls'][$type];
            $duration += $customer['duration'][$type];
        }
        //sums calls of subcustomer
        if(array_key_exists($id, $tempS) && array_key_exists($type, $tempS[$id])) {
            $calls += $tempS[$id][$type]['calls'];
            $duration += $tempS[$id][$type]['duration'];
        }
        //if there are calls, put in the result array
        if($calls>0) {
            $result[] = [
                'name' => $customer['name'],
                'label' => $type,
                'count' => $calls,
                'mins' => ceil($duration/ 60),
                'customerid' => $id
            ];
        }
}

但是上面得到最终结果数组的代码是不正确的地方,因为它不能正确添加所有调用和类型。

But the above code to get the final result array is not correct somewhere because it doesn't add all the calls and types correctly.

注意:这篇文章是在用户@Lipsyor的帮助下创建的。

Note: this post was created with the help of user @Lipsyor.

推荐答案

在创建临时数组时,您可以在数组 $ types 中收集类型。

You may collect types in the array $types while creating the temporary arrays.

首先声明数组:

$types = array();

每条 forach(...)对于 $ customers $ subcustomers 插入:

$types[$type] = true;

请注意,我使用数组的键来存储类型名称:使用此技巧,您永远不会插入重复项

Note that I use the key of the array to store type name: using this trick you never insert duplicates in the array.

此处是用于创建结果数组的代码:

Here the code for the creation of the result array:

$result = array();

foreach($tempC as $id => $customer) {

    foreach ($types as $type => $value) {

        $call = 0;
        $duration = 0;

        if(array_key_exists('calls', $customer) && array_key_exists($type, $customer['calls'])) {
            $call += $customer['calls'][$type];
            $duration += $customer['duration'][$type];
        }
        if(array_key_exists($id, $tempS) && array_key_exists($type, $tempS[$id])) {
            $call += $tempS[$id][$type]['calls'];
            $duration += $tempS[$id][$type]['duration'];
        }
        if($call>0) {
            $result[] = [
                'name' => $customer['name'],
                'label' => $type,
                'count' => $call,
                'mins' => ceil($duration / 60),
                'customerid' => $id
            ];
        }   
    }   
}

这篇关于对两个数组进行分组和求和的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆