将2d阵列中的行数据分组为3个列值;h: m〃;格式化了另一列中的值


Group row data in a 2d array by 3 column values and sum "h:m" formatted values in another column

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

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

有什么想法吗?感谢所有的帮助。

数据来自哪里?通常,这样的数据来自数据库,在这种情况下,以下语句将完全按照您的意愿执行:

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

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

好吧,有很多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);
  • 声明一个新数组
  • 遍历旧数组
  • 如果新数组为空,请将当前数组元素添加到其中
  • 如果没有,则对新数组进行迭代
    • 如果新数组的任何元素都与当前数组元素不匹配,请添加它
    • 否则,将当前元素的DURATION添加到相关新数组的元素中

如果你真的想用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));