【问题标题】:Group and sum items from array within foreach对 foreach 中数组中的项目进行分组和求和
【发布时间】:2015-06-25 13:15:25
【问题描述】:

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

包含结果集的两个数组是$customers$subcustomers

foreach($customers as $customer)
{
      foreach($subcustomers as $subcustomer)
      {
            if($subcustomer['parent'] == $customer['id'])
            {                        
                  if($customer['innumber'] == null && $subcustomer['innumber'] != null)
                  {                       
                      $chartInboundSub['name'] = $customer['name'];
                      $chartInboundSub['label'] = $subcustomer['innumber'];
                      $chartInboundSub['countInbound'] = $customer['count'];
                      $chartInboundSub['minsInbound'] = ceil($customer['duration'] / 60);
                      $chartInboundSub['customerid'] = $customer['id'];

                      array_push($out['chartInbound'], $chartInboundSub);
                  }
            }
       }
}

print_r($out['chartInbound'])的当前输出如下:

Array
(
    [0] => Array
        (
            [countInbound] => 426
            [minsInbound] => 340
            [name] => Telekomm
            [label] => 01-02
            [customerid] => 6
        )

    [1] => Array
        (
            [countInbound] => 1
            [minsInbound] => 2
            [name] => Telekomm
            [label] => 01-02
            [customerid] => 6
        )

    [2] => Array
        (
            [countInbound] => 3
            [minsInbound] => 21
            [name] => Telekomm
            [label] => 080
            [customerid] => 6
        )

    [3] => Array
        (
            [countInbound] => 1920
            [minsInbound] => 15766
            [name] => Telekomm
            [label] => 084
            [customerid] => 6
        )

    [4] => Array
        (
            [countInbound] => 2332
            [minsInbound] => 17521
            [name] => Telekomm
            [label] => 084
            [customerid] => 6
        )
    ...
)

以上结果需要namelabelcustomeridcountInboundminsInbound相加,所以:

期望的输出应该是:

Array
    (
        [0] => Array
            (
                [countInbound] => 427
                [minsInbound] => 342
                [name] => Telekomm
                [label] => 01-02
                [customerid] => 6
            )

        [1] => Array
            (
                [countInbound] => 3
                [minsInbound] => 21
                [name] => Telekomm
                [label] => 080
                [customerid] => 6
            )

        [2] => Array
            (
                [countInbound] => 4252
                [minsInbound] => 33287
                [name] => Telekomm
                [label] => 084
                [customerid] => 6
            )
        ...
    )

【问题讨论】:

  • 抱歉,我不太明白,如果 name、label 和 customerid 相同,您想将 countInboundminsInbound 相加吗?
  • @PHPeter:是的,没错

标签: php arrays foreach


【解决方案1】:

我认为这应该可行。我没有测试过代码,所以我不做任何承诺。

$map = array();
$i = 0;

foreach($customers as $customer)
{
      foreach($subcustomers as $subcustomer)
      {
            if($subcustomer['parent'] == $customer['id'])
            {                        
                  if($customer['innumber'] == null && $subcustomer['innumber'] != null)
                  {                       

                      $key = $customer['name'] . '/' . $subcustomer['innumber'] . '/' . $customer['id'];

                      if(isset($map[$key])) {
                            $out['chartInbound'][$map[$key]]['countInbound'] += $customer['count'];
                            $out['chartInbound'][$map[$key]]['minsInbound'] += ceil($customer['duration'] / 60);
                      }
                      else {
                          $out['chartInbound'][$i] = array(
                                  'name' => $customer['name'],
                                  'label' => $subcustomer['innumber'],
                                  'countInbound' => $customer['count'],
                                  'minsInbound' => ceil($customer['duration'] / 60),
                                  'customerid' => $customer['id'],
                          );
                          $map[$key] = $i++;
                    }
                  }
            }
       }
}

对于namelabelcustomerid 的每个组合,它都会创建一个对于该组合​​而言必须是唯一的字符串键。然后它检查该键是否已经有任何数据(通过在$out['chartInbound'] 中保留一个单独的键列表及其索引)。如果是这样,它只需添加countInboundminsInbound。如果不是,它会将整个 $chartInboundSub 放入 $out['chartInbound']

请注意,这依赖于唯一的密钥。例如,如果您在名称中允许 /,则可能并非如此。

【讨论】:

    【解决方案2】:

    我没有使用foreach 循环,而是使用每个PHP 数组都有的“迭代器”。

    假设数组已排序,那么单次记录“当前组 id”就足够了。

    我使用“预读”技术,因此不需要进行“if”测试来找出如何处理“当前记录”。

    working code as 'eval.in'

    代码:

    /**
     * Output stored in here...
     */
    $output = array();
    
    // groupId consists of:   name, label, customerid
    
    // read ahead - we need the current entry of the source array...
    $currentEntry = current($source);
    
    while ($currentEntry !== false) { // process the array / file / resultset etc.
    
        // start of a group... process the first record that every group has...
        $currentGroupId = getGroupId($currentEntry);
        $currentGroupCountInbound = $currentEntry['countInbound'];
        $currentGroupMinsInbound = $currentEntry['minsInbound'];
    
        // read the next record as we always 'read ahead' after processing a record...
        next($source);
        $currentEntry = current($source);
    
         while ($currentGroupId == getGroupId($currentEntry)) {
            // same group = total the values...
    
           $currentGroupCountInbound += $currentEntry['countInbound'];
           $currentGroupMinsInbound += $currentEntry['minsInbound'];
    
           // next entry in the input array - will end this group if not the same...
           next($source);
           $currentEntry = current($source);
        }
    
        // end of the current group -- output the information...
        // add it to an array... or whatever...
        $output[] = array('groupid' => $currentGroupId,
                           'countInbound' => $currentGroupCountInbound,
                           'minsInbound' => $currentGroupMinsInbound);
    }
    
    // show the output...
    echo '<pre>';
    print_r($output);
    echo '</pre>';
    exit;
    
    // ---------------------------------
    function getGroupId($entry = array())
    {
        if (empty($entry)) {
            return array();
        }
    
        return array(
            $entry['name'], $entry['label'], $entry['customerid']
        );
    }
    

    输出:

    Array(
        [0] => Array(
                [groupid] => Array(
                        [0] => Telekomm
                        [1] => 01-02
                        [2] => 6
                    )
                [countInbound] => 427
                [minsInbound] => 342
            )
    
        [1] => Array(
                [groupid] => Array(
                        [0] => Telekomm
                        [1] => 080
                        [2] => 6
                    )
                [countInbound] => 3
                [minsInbound] => 21
            )
    
        [2] => Array(
                [groupid] => Array(
                        [0] => Telekomm
                        [1] => 084
                        [2] => 6
                    )
                [countInbound] => 4252
                [minsInbound] => 33287
            )
    )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-21
      • 1970-01-01
      • 1970-01-01
      • 2020-08-06
      • 2020-04-25
      • 2023-02-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多