如何按照税收和#39;概念'对数组进行分组和SUM属性' val'?
我想在税和概念相同的时候创建一个单独的对象,也是SUM的val。
我尝试使用简单的foreach和验证,但不起作用。
感谢。
echo json_encode($array);
阵列打印
[
{
"tax": "10",
"concept": "TUC",
"val": "10"
},
{
"tax": "10",
"concept": "TUC",
"val": "86"
},
{
"tax": "15",
"concept": "TUC",
"val": "8"
},
{
"tax": "11",
"concept": "IPS",
"val": "6"
},
{
"tax": "11",
"concept": "IPS",
"val": "45"
}
]
预期结果
[
{
"tax": "10",
"concept": "TUC",
"val": "96"
},
{
"tax": "15",
"concept": "TUC",
"val": "8"
},
{
"tax": "11",
"concept": "IPS",
"val": "51"
}
]
答案 0 :(得分:4)
您可以在此处使用array_reduce()
。您将tax
值用作要分组的键,并将数组缩减为唯一val
元素,同时生成$array = // your array from above
$result = array_reduce($array, function($carry, $item) {
if(!isset($carry[$item->tax])) {
$carry[$item->tax] = $item;
} else {
$carry[$item->tax]->val += $item->val;
}
return $carry;
});
$result = array_values($result);
echo json_encode($result);
值的总和。这种方法的唯一警告是将其转换为JSON将使PHP认为外部元素是一个对象而不是一个数组(即使它是一个数组,这是因为我们最终使用非默认数组索引)。但是,通过调用array_values()
可以轻松减轻这种情况。
[{
"tax": "10",
"concept": "TUC",
"val": 96
}, {
"tax": "15",
"concept": "TUC",
"val": "8"
}, {
"tax": "11",
"concept": "IPS",
"val": 51
}]
您可以从this demo看到它产生:
SoftLayer_Account::getVirtualGuests(mask="mask[inboundPrivateBandwidthUsage,inboundPublicBandwidthUsage,outboundPrivateBandwidthUsage,outboundPublicBandwidthUsage]")
答案 1 :(得分:1)
$array // Your array
$result = [];
array_walk($array, function($object) use (&$result) {
$notExist = true;
foreach ($result as $item) {
if ($item->tax == $object->tax && $item->concept == $object->concept) {
$item->val += $object->val;
$notExist = false;
break;
}
}
if ($notExist) {
array_push($result, $object);
}
});
echo json_encode($result);
答案 2 :(得分:0)
首先将对象分组:
$groups = [];
foreach($array as $object){
$groups[$object->tax . "\0" . $object->concept] = $object;
// I use the NUL byte to delimit, assuming it is absent in $tax and $concept
}
然后将每个组映射到一个总结对象。
$output = array_map(function(array $group){
$object = new stdClass;
$object->tax = $group[0]->tax;
$object->concept = $group[0]->concept;
$object->val = array_reduce($group, function($carry, $item){
return $carry + $item->val;
}, 0);
return $object;
}, $groups);
答案 3 :(得分:0)
添加两个对象的税和概念属性相等的所有" val" s并设置" val"每个对象的属性为此数字。
在伪代码中它会像......
//Loop through all elements of array starting at 0
//InnerLoop through all elements of array starting at 0
//test if outer and inner object have equivalent tax and concept properties (and aren't the same location)
//if so then add inner loop object's val to outer loop object's val
最后,只需删除数组中的重复项,这看起来就像..
//Loop through all elements of array starting at the end and going to 0
//InnerLoop through all elements of array starting at 1 less than outer loop going to 0
//test if inner and outer loop object's have equal tax and concept properties
//if so then delete the object at the inner loops location
答案 4 :(得分:0)
<?php
$arr_str = '[
{"tax":"10", "concept":"TUC", "val":"10"},
{"tax":"10", "concept":"TUC", "val":"86"},
{"tax":"15", "concept":"TUC", "val":"8"},
{"tax":"11", "concept":"IPS", "val":"6"},
{"tax":"11", "concept":"IPS", "val":"45"}
]';
$arr = json_decode($arr_str);
$tmp_array = [];
foreach ($arr as $e) {
// combine "tax" and "concept" so we can use both of them as key. Use "_" as delimiter.
$key = $e->tax . "_" . $e->concept;
// sum the "val" if the key exists, otherwise assign it
isset($tmp_array[$key]) ? $tmp_array[$key] += $e->val : $tmp_array[$key] = $e->val;
}
$grouped_array = [];
foreach ($tmp_array as $k => $v) {
// ungroup the key so we can create an array like the original one
$tmp = explode("_", $k);
$grouped_array[] = (object)["tax" => $tmp[0], "concept" => $tmp[1], "val" => $v];
}
echo json_encode($grouped_array);
?>