PHP 总结两个键具有相同值的数组条目
PHP sum up array entries where two keys have the same value
我有以下数组,我想在其中总结源和目标相同的所有条目的 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)
<?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);
不是很漂亮,但这是我使用嵌套 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);
这个怎么样?我觉得有点简短。
$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);
另一种选择。不是最好,但会工作。
$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);
我有以下数组,我想在其中总结源和目标相同的所有条目的 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)
<?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);
不是很漂亮,但这是我使用嵌套 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);
这个怎么样?我觉得有点简短。
$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);
另一种选择。不是最好,但会工作。
$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);