【问题标题】:I have two arrays , with id and totals. I want to add totals if ID is same. How do I do?我有两个数组,带有 id 和总数。如果 ID 相同,我想添加总数。我该怎么办?
【发布时间】:2019-07-25 09:13:17
【问题描述】:

我有 2 个数组。像这样的。

  $res1 = [
     ['ID' => 60,'TOTAL' => 500],
     ['ID' => 61,'TOTAL' => 600],
     ['ID' => 63,'TOTAL' => 500]
  ];
 $res2 = [
     ['ID' => 60,'TOTAL' => 600],
     ['ID' => 61,'TOTAL' => 700],
     ['ID' => 64,'TOTAL' => 800]
  ];

我想将 $res1 和 $res2 数组与 ID 合并,如果 ID 相等,则将总数相加,否则如果 ID 不匹配,那么我也应该将其保留在数组中。

这是我尝试过的,需要帮助以进一步提高性能。

 foreach ($res1 as $id1 => $val1) {
        foreach ($res2 as $id2 => $val2) {
            $r =array();
            if ($val1['ID'] == $val2['ID']) {
                $r['ID'] = $val1['ID'];
                $r['TOTAL'] = $val1['TOTAL'] + $val2['TOTAL'];
            }else{
                // MISSING Something here 
            }
            $result[] = $r;
        }

    }

预期的结果应该是

$result = [
     ['ID' => 60,'TOTAL' => 1100],
     ['ID' => 61,'TOTAL' => 1300],
     ['ID' => 63,'TOTAL' => 500],
     ['ID' => 64,'TOTAL' => 800]
  ];

【问题讨论】:

  • 使用这些数组效率不是很高。你是怎么把它们弄成这样的?更好的数组是:$totals1 = [60 => 500, 61 => 600, 63 => 500];$totals2 = [60 => 600, 61 => 700, 64 => 800];
  • @KIKOSoftware 我无法更改数组表示。可能需要现有解决方案

标签: php


【解决方案1】:

在我给出这个答案之前,如果这来自一个数据库表,那么最好只在该层中进行求和。也就是说,当数组增长时,它会变慢。

我要做的是首先获取所有 ID。然后根据所有 ID 循环,然后搜索它们各自的总数和总和。像这样:

$result = [];
$ids = array_unique(array_merge(array_column($res1, 'ID'), array_column($res2, 'ID')));
foreach ($ids as $id) {
    if (empty($result[$id])) { // initialization
        $result[$id] = ['ID' => $id, 'TOTAL' => 0];
    }

    $res1_key = array_search($id, array_column($res1, 'ID'));
    $res2_key = array_search($id, array_column($res2, 'ID'));

    $sum = array_sum([
        $res1_key !== false ? $res1[$res1_key]['TOTAL'] : 0,
        $res2_key !== false ? $res2[$res2_key]['TOTAL'] : 0,
    ]);

    $result[$id]['TOTAL'] = $sum;
}

基本上获取第一个和第二个数组上存在的所有 id。根据IDS循环,初始化容器,在两者上搜索ID总数,然后求和,然后分配到初始化的容器中。

旁注:这仅考虑每个数组集的一个唯一 ID。如果两个数组中都有重复项,例如$res1 有两个ID = 60,则可以对其进行改造以使用array_keys 来获取多个搜索值,而不是array_search

【讨论】:

    【解决方案2】:
    $res1 = [
        ['ID' => 60,'TOTAL' => 500],
        ['ID' => 61,'TOTAL' => 600],
        ['ID' => 63,'TOTAL' => 500]
     ];
    $res2 = [
        ['ID' => 60,'TOTAL' => 600],
        ['ID' => 61,'TOTAL' => 700],
        ['ID' => 64,'TOTAL' => 800]
     ];
    
     //store result here
     $result = array();
    
     //check duplicates in res1
     foreach($res1 as $r1){
        $has_pair = false;
        foreach($res2 as $r2){
            if($r1['ID'] == $r2['ID']){
                //if res 1 has a duplicate, then add them both
                $has_pair = true;
                $arr = array(
                    'ID' => $r1['ID'],
                    'TOTAL' => ($r1['TOTAL'] + $r2['TOTAL']),
                );
               //add them to $result
                array_push($result,$arr);
            }
        }
        if(!$has_pair){
            //if pair in $res1 then add them here instead
            array_push($result,$r1);
        }
     }
    
     //check duplicates for res2
     foreach($res2 as $r1){
        $has_pair = false;
        foreach($result as $r2){
            if($r1['ID'] == $r2['ID']){
                $has_pair = true;
            }
        }
        if(!$has_pair){
            array_push($result,$r1);
        }
     }
     print_r($result);
    

    【讨论】:

      【解决方案3】:

      你可以使用下面的代码

      
      $res1 = [
         ['ID' => 60,'TOTAL' => 500],
         ['ID' => 61,'TOTAL' => 600],
         ['ID' => 63,'TOTAL' => 500]
      ];
      $res2 = [
          ['ID' => 60,'TOTAL' => 600],
          ['ID' => 61,'TOTAL' => 700],
          ['ID' => 64,'TOTAL' => 800]
      ];
      
      $results = array();
      
      foreach( array_merge( $res1, $res2) as $r ) {
          if( !isset ( $results [ $r['ID'] ] ) ) {
              $results[ $r['ID'] ] = 0;
          }
      
          $results[ $r['ID'] ]  += $r['TOTAL'];
      } 
      
      $reformatResults = array();
      
      foreach( $results as $key => $total ) {
          $reformatResults[$key] = $total;
      }
      echo '<pre>';
      print_r($reformatResults);
      

      在此处查看演示。 https://3v4l.org/Z6Bhv

      【讨论】:

        【解决方案4】:

        您可以使用函数array_walk。我的解决方案比使用foreach in foreach 或使用array_search 更快。这里链接到解决方案https://3v4l.org/tC8Xu

        <?php
        $res1 = [
             ['ID' => 60,'TOTAL' => 500],
             ['ID' => 61,'TOTAL' => 600],
             ['ID' => 63,'TOTAL' => 500]
          ];
         $res2 = [
             ['ID' => 60,'TOTAL' => 600],
             ['ID' => 61,'TOTAL' => 700],
             ['ID' => 64,'TOTAL' => 800]
          ];
        
          function summTotal(&$result, $parts) {
            array_walk($parts, function($item) use (&$result){
              if (isset($result[$item['ID']])) {
                  $result[$item['ID']]['TOTAL'] += $item['TOTAL']; 
              } else {
                  $result[$item['ID']] = $item;
              }
            });
          }
        
          $result = [];
        
          summTotal($result, $res1);
          summTotal($result, $res2);
        
          print_r($result);
        

        【讨论】:

          【解决方案5】:

          试试这个

          $result = [];
          $merge = array_merge($res1,$res2);
          $resId = array_unique(array_column($merge,'ID'));
          foreach ($resId as $vId) {
              $tempValue = [];
              foreach ($merge as $vm) {
                  if (!array_key_exists($vId, $tempValue)) {
                      $tempValue[$vId] = 0;
                  }
          
                  if ($vId == $vm['ID']) {
                      $tempValue[$vId] += $vm['TOTAL']; 
                  }
              }
          
              $result[] = ['ID' => $vId,'TOTAL' => $tempValue[$vId]];
          }
          
          return json_encode($result);
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2019-10-16
            • 1970-01-01
            • 2020-12-20
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-12-06
            相关资源
            最近更新 更多