【问题标题】:Group array objects by properties按属性分组数组对象
【发布时间】:2016-08-10 18:00:27
【问题描述】:

如何按'tax'和'concept'和SUM属性'val'对数组进行分组?

我想在税收和概念相同的情况下创建一个对象,也就是对 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"
 }
]

【问题讨论】:

  • 我尝试了简单的 foreach 和内部验证,但不起作用。 - 显示您的代码

标签: php


【解决方案1】:

您可以在此处使用array_reduce()。您将使用 tax 值作为要分组的键,并将数组减少为唯一的 tax 元素,同时生成 val 值的总和。这种方法唯一需要注意的是,将其转换为 JSON 会使 PHP 认为外部元素是一个对象而不是数组(即使它是一个数组,这是因为我们最终使用了非默认数组索引)。但是,调用array_values() 可以轻松缓解这种情况。

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

你可以从this demo看到它产生的:

[{
    "tax": "10",
    "concept": "TUC",
    "val": 96
}, {
    "tax": "15",
    "concept": "TUC",
    "val": "8"
}, {
    "tax": "11",
    "concept": "IPS",
    "val": 51
}]

【讨论】:

  • 对我不起作用,另外,您正在考虑将 tax 的值作为键。当 both taxconcept 相同时,OP 想要分组,因此密钥应该是这两者的组合。
  • @VicenteOlivertRiera - 这就是为什么有一个演示链接,可以尝试一下,看看它是否有效。此外,OP 的数据没有任何需要该键的值(当税与另一个元素匹配时,它的概念也是如此),但这是一个简单的修改,可以留给 OP 实施。
【解决方案2】:
$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);

【讨论】:

    【解决方案3】:

    首先将对象分组:

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

    【讨论】:

      【解决方案4】:
      <?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);
      ?>
      

      【讨论】:

        猜你喜欢
        • 2014-09-22
        • 1970-01-01
        • 2019-04-15
        • 1970-01-01
        • 1970-01-01
        • 2015-12-31
        • 2021-11-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多