按属性对数组对象进行分组

时间:2016-08-10 18:00:28

标签: php

如何按照税收和#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"
 }
]

5 个答案:

答案 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);
?>