简体   繁体   English

PHP总结两个键具有相同值的数组条目

[英]PHP sum up array entries where two keys have the same value

I have the following array, in which I want to sum up the total_volume for all entries where the source and the target are the same. 我有以下数组,我想在其中总结源和目标相同的所有条目的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
    )
)

The resulting array should look like this: 结果数组应如下所示:

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

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

My first thought would be to llop through the existing array and check via a nested loop over the ResultArray whether an entry with the matching source-target-pair already exists. 我首先想到的是遍历现有数组,并通过ResultArray上的嵌套循环检查是否已经存在具有匹配的源-目标对的条目。

Is there an other way using array_walk() or a similar method? 还有其他使用array_walk()或类似方法的方法吗?

Thanks in advance for your help! 在此先感谢您的帮助!

not pretty but heres how I would do it with a nested foreach; 不是很漂亮,但是这是我将如何使用嵌套的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);

This is a fast try (sorry, it uses twice array_walk) 这是一个快速尝试(对不起,它使用了两次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);

How about this? 这个怎么样? A bit briefer I think. 我认为要简短一些。

$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);

Another alternative. 另一种选择。 Not best but will work. 并不是最好,但是会起作用。

$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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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