【问题标题】:PHP sum up array entries where two keys have the same valuePHP总结两个键具有相同值的数组条目
【发布时间】:2016-06-07 09:43:47
【问题描述】:

我有以下数组,我想在其中汇总源和目标相同的所有条目的 total_volume。

Array (
[0] => Array
    (
        [source] => ABC
        [target] => DEF
        [total_volume] => 10
    )

[1] => Array
    (
        [source] => ABC
        [target] => GHI
        [total_volume] => 5
    )
[2] => Array
    (
        [source] => ABC
        [target] => DEF
        [total_volume] => 5
    )
)

生成的数组应如下所示:

ResultArray (
[0] => Array
    (
        [source] => ABC
        [target] => DEF
        [total_volume] => 15
    )

[1] => Array
    (
        [source] => ABC
        [target] => GHI
        [total_volume] => 5
    )
)

我的第一个想法是遍历现有数组并通过 ResultArray 上的嵌套循环检查是否已经存在具有匹配源-目标-对的条目。

还有其他方法使用 array_walk() 或类似的方法吗?

提前感谢您的帮助!

【问题讨论】:

  • 我可以使用原始代码来实现,您需要 array_walk 还是原始代码??
  • 我对任何解决方案都很满意,因为我不知道如何解决这个问题。所以 raw 对我来说很好。非常感谢!

标签: php arrays loops array-map array-walk


【解决方案1】:

不漂亮,但我将如何使用嵌套的 foreach 来做到这一点;

$aStartingArray = array();
$aStartingArray[] = array('source'=>'ABC', 'target' => 'DEF', 'total_volume' => 10); 
$aStartingArray[] = array('source'=>'ABC', 'target' => 'GHI', 'total_volume' => 5); 
$aStartingArray[] = array('source'=>'ABC', 'target' => 'DEF', 'total_volume' => 5); 


$aSortedArray = array();

foreach ($aStartingArray as $aArray) {

    $bSet = false;

    foreach ($aSortedArray as $iPos => $aTempSortedArray) {

        if(
            $aTempSortedArray['source'] == $aArray['source'] && 
            $aTempSortedArray['target'] == $aArray['target']){

            $aSortedArray[$iPos]['total_volume'] += $aArray['total_volume'];

            $bSet = true;
        }

    }

    if(!$bSet) {

        $aSortedArray[] = array(
            'source' => $aArray['source'], 
            'target' => $aArray['target'], 
            'total_volume' => $aArray['total_volume']
            );
    }
}


var_dump($aSortedArray);

【讨论】:

    【解决方案2】:

    这是一个快速尝试(抱歉,它使用了两次 array_walk)

    <?php
    
    $a = [
        ['source' => 'ABC', 'target' => 'DEF', 'total_volume' => 10 ],
        ['source' => 'ABC', 'target' => 'GHI', 'total_volume' => 5 ],
        ['source' => 'ABC', 'target' => 'DEF', 'total_volume' => 5 ],
    ];
    
    $tmp = [];
    
    array_walk($a, function (&$item, $key) use (&$tmp) {
        $resKey = $item['source'].'_'.$item['target'];
        if (!isset($result[$resKey])) {
            $result[$resKey] = 0;
        }
        $tmp[$resKey] += $item['total_volume'];
    });
    
    $result = [];
    array_walk($tmp, function (&$item, $key) use (&$result) {
        list ($source, $target) = explode('_', $key);
        $result[] = ['source' => $source, 'target' => $target, 'total_volume' => $item];
    });
    
    var_dump($result);
    

    【讨论】:

    • 我也尝试了答案但没有完成,很好的答案。
    【解决方案3】:

    这个怎么样?我觉得简单一点。

    $a = [
        ['source' => 'ABC', 'target' => 'DEF', 'total_volume' => 10 ],
        ['source' => 'ABC', 'target' => 'GHI', 'total_volume' => 5 ],
        ['source' => 'ABC', 'target' => 'DEF', 'total_volume' => 5 ],
    ];
    $result = $result2 = [];
    array_walk($a, function(&$item, $key) use(&$result) {
        if(! isset($result[$item['source']]))
            $result[$item['source']] = [];
        if(! isset($result[$item['source']][$item['target']]))
            $result[$item['source']][$item['target']] = 0;
        $result[$item['source']][$item['target']] += $item['total_volume'];
    });
    foreach($result as $key => $val) {  
        foreach($val as $k => $v) {
            $result2[] = [$key,$k,$v];
        }
    }
    print_r($result2);
    

    【讨论】:

      【解决方案4】:

      另一种选择。不是最好的,但会起作用。

      $arr = [
          ['source' => 'ABC', 'target' => 'DEF', 'total_volume' => 10 ],
          ['source' => 'ABC', 'target' => 'GHI', 'total_volume' => 5 ],
          ['source' => 'ABC', 'target' => 'DEF', 'total_volume' => 5 ],
      ];
      
      $res = $resulrArr = [];
      foreach($arr as $record){
        $record = array_values($record);  
        $res[$record[0].'_'.$record[1]] = !empty($res[$record[0].'_'.$record[1]]) ? $res[$record[0].'_'.$record[1]] + $record[2] : $record[2];  
      }
      
      $resulrArr = array_map(function($v,$k){
        $data = explode('_',$k);
        $resulrArr['source'] = $data[0];
        $resulrArr['target'] = $data[1];
        $resulrArr['total_volume'] = $v;
        return $resulrArr;
      },$res,array_keys($res));
      
      echo '<pre>'; print_r($resulrArr);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-07
        • 1970-01-01
        • 2015-01-04
        • 2022-01-17
        • 1970-01-01
        • 2014-03-04
        相关资源
        最近更新 更多