按列对行进行分组并对组内的另一列求和

Group rows by column and sum another column within groups

我有一个数组,如下所示:

array(480) {
  [0]=>
  array(2) {
    ["tag_id"]=>
    string(4) "6291"
    ["az"]=>
    int(5)
  }
  [1]=>
  array(2) {
    ["tag_id"]=>
    string(4) "6291"
    ["az"]=>
    int(4)
  }
  [2]=>
  array(2) {
    ["tag_id"]=>
    string(4) "6311"
    ["az"]=>
    int(4)
  }
  [3]=>
  array(2) {
    ["tag_id"]=>
    string(4) "6427"
    ["az"]=>
    int(4)
  }

如果“Tag_ID”相同,我如何减少数组,以便“az”对“az”的所有值求和? 预期输出:

array(479) {
      [0]=>
      array(2) {
        ["tag_id"]=>
        string(4) "6291"
        ["az"]=>
        int(9)
      }
      
      [1]=>
      array(2) {
        ["tag_id"]=>
        string(4) "6311"
        ["az"]=>
        int(4)
      }
      [2]=>
      array(2) {
        ["tag_id"]=>
        string(4) "6427"
        ["az"]=>
        int(4)
      }

我试过 array_reduce 但无法确定要在其中使用的功能。 非常感谢!

我创建了一些示例代码,理论上只要您知道 tag_id 可能是什么,它就会执行您需要它执行的操作,它使用数组过滤器并检查是否 tag_id等于您输入的内容:

$arr = array(
    array("tag_id" => "6291", "az" => "int(5)"),
    array("tag_id" => "6291", "az" => "int(4)"),
    array("tag_id" => "6311", "az" => "int(4)"),
);

$results = array_filter($arr, function ($item) {
    if ($item["tag_id"] == "6291") {
         return true;   
    }
    return false; 
});
              
foreach ($results as $result) {
    echo "tag_id = " . $result["tag_id"];    
    echo "az = " . $result["az"] . PHP_EOL;
} 

您必须使用 array_walk() 来修改数组。 array_reduce()是计算单个值,不改变数组本身。

我会这样做:

<?php

$array = [
    [
        'tag_id' => "6291",
        'az' => 5,
    ],
    [
        'tag_id' => "6291",
        'az' => 4,
    ],
    [
        'tag_id' => "6311",
        'az' => 4,
    ],
    [
        'tag_id' => "6427",
        'az' => 4,
    ]
];

$tag_id_indexes = []; // To store the index of the first tag_id found.

array_walk(
    $array,
    function ($sub_array, $index) use (&$array, &$tag_id_indexes) {
        // Store the index of the first tag_id found.
        if (!isset($tag_id_indexes[$sub_array['tag_id']])) {
            $tag_id_indexes[$sub_array['tag_id']] = $index;
        }
        else { // This tag_id already exists so we'll combine it.
            // Get the index of the previous tag_id.
            $first_tag_id_index = $tag_id_indexes[$sub_array['tag_id']];
            // Sum the az value.
            $array[$first_tag_id_index]['az'] += $sub_array['az'];
            // Remove this entry.
            unset($array[$index]);
        }
    }
);

print "The reduced array but with the original indexes:\n" . var_export($array, true) . "\n";

// If you want new indexes.
$array = array_values($array);

print "The reduced array with new indexes:\n" . var_export($array, true) . "\n";

你可以在这里测试:https://onlinephp.io/c/58a11

这是输出:

The reduced array but with the original indexes:
array (
  0 => 
  array (
    'tag_id' => '6291',
    'az' => 9,
  ),
  2 => 
  array (
    'tag_id' => '6311',
    'az' => 4,
  ),
  3 => 
  array (
    'tag_id' => '6427',
    'az' => 4,
  ),
)
The reduced array with new indexes:
array (
  0 => 
  array (
    'tag_id' => '6291',
    'az' => 9,
  ),
  1 => 
  array (
    'tag_id' => '6311',
    'az' => 4,
  ),
  2 => 
  array (
    'tag_id' => '6427',
    'az' => 4,
  ),
)

您可以自然地使用array_reduce:

$res = array_reduce(
    $array,
    function($ac, $el) {
        $ac[$el['tag_id']] += $el['az'];
        return $ac;
    },
    []
);

print_r($res);

它将以 tag_id 为键并以 az 为值构建数组:

Warning: Undefined array key 6291

Warning: Undefined array key 6311

Warning: Undefined array key 6427
Array
(
    [6291] => 9
    [6311] => 4
    [6427] => 4
)

当你需要恢复源数组结构时使用array_map

$res = array_map(
    fn($k, $v) => ['tag_id' => $k, 'az' => $v],
    array_keys($res),
    $res
);

PHP array_reduce array_map