按 3 列值对二维数组中的行数据进行分组,并在另一列中对“h:m”格式的值求和

问题描述 投票:0回答:4

我有一个形式为的多维数组;

Array
(
    [0] => Array
        (
            [DATE] => 05-19-2011
            [PERSON] => Bob Hope
            [ITEM] => Holiday
            [DURATION] => 04:00
        )
    [1] => Array
        (
            [DATE] => 05-19-2011
            [PERSON] => Bob Hope
            [ITEM] => Work
            [DURATION] => 05:00
        )
    [2] => Array
        (
            [DATE] => 05-19-2011
            [PERSON] => Bob Hope
            [ITEM] => Holiday
            [DURATION] => 06:00
        )
    [3] => Array
        (
            [DATE] => 05-19-2011
            [PERSON] => Bob Hope
            [ITEM] => Work
            [DURATION] => 05:00
        )
    [4] => Array
        (
            [DATE] => 05-19-2011
            [PERSON] => Joe Bloggs
            [ITEM] => Holiday
            [DURATION] => 02:00
        )
    [5] => Array
        (
            [DATE] => 05-19-2011
            [PERSON] => Joe Bloggs
            [ITEM] => Work
            [DURATION] => 03:00
        )
    [6] => Array
        (
            [DATE] => 05-19-2011
            [PERSON] => Joe Bloggs
            [ITEM] => Holiday
            [DURATION] => 03:00
        )
    [7] => Array
        (
            [DATE] => 05-19-2011
            [PERSON] => Joe Bloggs
            [ITEM] => Work
            [DURATION] => 02:00
        )
)

并想整理结果,合计每个人的假期和工作,以便我可以以以下形式输出一些东西;

Array
(
    [0] => Array
        (
            [DATE] => 05-19-2011
            [PERSON] => Bob Hope
            [ITEM] => Holiday
            [DURATION] => 10:00
        )
    [1] => Array
        (
            [DATE] => 05-19-2011
            [PERSON] => Bob Hope
            [ITEM] => Work
            [DURATION] => 10:00
        )
    [2] => Array
        (
            [DATE] => 05-19-2011
            [PERSON] => Joe Bloggs
            [ITEM] => Holiday
            [DURATION] => 05:00
        )
    [3] => Array
        (
            [DATE] => 05-19-2011
            [PERSON] => Joe Bloggs
            [ITEM] => Work
            [DURATION] => 05:00
        )
)

有什么想法吗?任何帮助表示赞赏。

php arrays multidimensional-array sum grouping
4个回答
2
投票

数据从哪里来?通常,此类数据来自数据库,在这种情况下,以下语句将完全满足您的要求:

SELECT 
   SUM(DURATION),
   ITEM,
   PERSON
FROM
   yourtable
GROUP BY 
   PERSON, 
   ITEM;

编辑:如果你也想按项目对它们进行分组,只需声明即可。


1
投票

好吧,很多 foreach 的,但你基本上是在一个单独的结构中添加值,并重新排列结果数组:

$items = array(
    0 => Array(
        'DATE' => '05-19-2011',
        'PERSON' => 'Bob Hope',
        'ITEM' => 'Holiday',
        'DURATION' => '10:00',
    ),
    1 => Array(
            'DATE' => '05-19-2011',
            'PERSON' => 'Bob Hope',
            'ITEM' => 'Work',
            'DURATION' => '10:00',
    ),
    2 => Array(
            'DATE' => '05-19-2011',
            'PERSON' => 'Joe Bloggs',
            'ITEM' => 'Holiday',
            'DURATION' => '05:00',
    ),
    3 => Array(
            'DATE' => '05-19-2011',
            'PERSON' => 'Joe Bloggs',
            'ITEM' => 'Work',
            'DURATION' => '05:00',
    ),
);

foreach($items as $key=>$value){
    $item = $value['ITEM'];
    $out[$value['PERSON']][$value['DATE']][$value['ITEM']] += $value['DURATION'];
}

foreach($out as $person=>$data){
    foreach($data as $date=>$items){
        foreach($items as $item=>$duration){
            $result[] = array(
                'PERSON'=>$person,
                'DATE'=>$date,
                'ITEM'=>$item,
                'DURATION'=>$duration,
            );
        }
    }
}
print_r($result);

0
投票
  • 声明一个新数组。
  • 迭代旧数组
  • 如果新数组为空,则将当前数组元素加入其中
  • 如果不是,遍历新数组
    • 如果没有新数组的元素与当前数组元素匹配,则添加它
    • else 将当前元素的 DURATION 添加到相关的新数组的元素

0
投票

如果你真的想用 PHP 解决这个问题,我建议不要嵌套太多循环。这是我的解决方案(顺便说一句,看起来很丑陋。):

$result = array();
foreach ($data as $row) {
    $key = $row['PERSON'] . '|' . $row['ITEM'];
    $tmp = explode(':', $row['DURATION']);
    $row['DURATION'] = $tmp[0] * 60 + $tmp[1];

    if (!isset($result[$key])) {
        $result[$key] = $row;
    } else {
        $result[$key]['DURATION'] += $row['DURATION'];
    }
}

$result = array_map(function($v) {
    $v['DURATION'] = strftime('%M:%S', $v['DURATION']);

    return $v;
}, array_values($result));
© www.soinside.com 2019 - 2024. All rights reserved.