PHP:按id对对象数组进行分组,同时对对象值求和[重复]

pkwftd7m  于 2023-04-19  发布在  PHP
关注(0)|答案(4)|浏览(127)

此问题已在此处有答案

Group 2d array's row data by one column and sum another column within each group to produce a reduced 2d array(3个答案)
11个月前关闭。
我在PHP中操作一个对象数组时遇到了困难。我需要按id对对象进行分组,同时对points求和。

起始对象数组:

[
  {
    "id": "xx",
    "points": 25
  },
  {
    "id": "xx",
    "points": 40
  },
  {
    "id": "xy",
    "points": 40
  },
]

我需要的:

[
  {
    "id": "xx",
    "points": 65
  },
  {
    "id": "xy",
    "points": 40
  },
]

作为一名前端人员,我在PHP中的对象/数组操作方面遇到了困难。任何帮助都将不胜感激!

oxf4rvwz

oxf4rvwz1#

我希望这个答案对你有帮助首先我将把对象改为数组并再次将结果返回给数组

$values =[
  [
    "id"=> "xx",
    "points"=> 25
  ],
  [
    "id"=> "xx",
    "points"=> 40
  ],
  [
    "id"=> "xy",
    "points"=> 40
  ],
];
$res  = array();
foreach($values as $vals){
  if(array_key_exists($vals['id'],$res)){
    $res[$vals['id']]['points']    += $vals['points'];
    $res[$vals['id']]['id']        = $vals['id'];
  }
  else{
    $res[$vals['id']]  = $vals;
  }
}
$result = array();
foreach ($res as $item){
  $result[] = (object) $item;
}

输出enter image description here

jhkqcmku

jhkqcmku2#

  • 将JSON解析为对象
  • 汇总数据
  • 返回JSON
$json = <<<'_JSON'
[
  {
    "id": "xx",
    "points": 25
  },
  {
    "id": "xx",
    "points": 40
  },
  {
    "id": "xy",
    "points": 40
  }
]
_JSON;

$aggregate = [];
foreach(json_decode($json) as $data) {
    if(!isset($aggregate[$data->id])) $aggregate[$data->id] = 0;
    $aggregate[$data->id] += $data->points;
}

$output = [];
foreach($aggregate as $id => $points) {
    $output[] = ['id' => $id, 'points' => $points];
}

echo json_encode($output);
[{"id":"xx","points":65},{"id":"xy","points":40}]
qc6wkl3g

qc6wkl3g3#

您可以使用array_reduce内置函数来完成这项工作。此外,当循环对象的数组(回调)时,您应该检查结果数组是否具有当前项目的ID,以验证是否需要将项目添加到结果数组或使点的总和属性。
下面是一个例子:

// a dummy class just to replicate the objects with ID and points attributes
class Dummy 
{
    public $id;
    public $points;
    
    public function __construct($id, $points)
    {
        $this->id = $id;
        $this->points = $points;
    }
}

// the array of objects
$arr = [new Dummy('xx', 25), new Dummy('xx', 40), new Dummy('xy', 40)];

// loop through the array
$res = array_reduce($arr, function($carry, $item) {
    // holds the index of the object that has the same ID on the resulting array, if it stays NULL means it should add $item to the result array, otherwise calculate the sum of points attributes
    $idx = null;
    // trying to find the object that has the same id as the current item
    foreach($carry as $k => $v)
        if($v->id == $item->id) {
            $idx = $k;
            break;
        }
    // if nothing found, add $item to the result array, otherwise sum the points attributes
    $idx === null ? $carry[] = $item:$carry[$idx]->points += $item->points;
    // return the result array for the next iteration
    return $carry;
}, []);

这将导致如下结果:

array(2) {
  [0]=>
  object(Dummy)#1 (2) {
    ["id"]=>
    string(2) "xx"
    ["points"]=>
    int(65)
  }
  [1]=>
  object(Dummy)#3 (2) {
    ["id"]=>
    string(2) "xy"
    ["points"]=>
    int(40)
  }
}

希望对您有所帮助,请随时寻求进一步的帮助。

jq6vz3qz

jq6vz3qz4#

让我们使用一个名为$map的辅助变量:

$map = [];

构建您的Map:

foreach ($input => $item) {
    if (!isset($map[$item["id"]])) $map[$item["id"]] = 0;
     $map[$item["id"]] += $item["points"];
}

现在让我们构建输出:

$output = [];
foreach ($map as $key => $value) {
    $output[] = (object)["id" => $key, "points" => $value];
}

相关问题