对二维数组中的数据进行分组和求和,然后将总计映射到另一个二维数组

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

我需要对一个数组中由另一列分组的一列值求和,并根据特定列值将这些结果映射到另一个数组。

示例输入:

$milestones = [
    [
        'id' => '1578453e53090b',
        'milestone' => 'Wireframe',
        'assigned_to' => 9
    ],
    [
        'id' => '1578453e530975',
        'milestone' => 'Development'
    ],
    [
        'id' => '1578453e530943',
        'milestone' => 'Design',
        'assigned_to' => 2
    ]
];

$tasks = [
    [
        'id' => '15786dc59333f2',
        'status' => 'Open',
        'progress' => 5,
        'milestone' => '1578453e53090b'
    ],
    [
        'id' => '15786dc669d451',
        'status' => 'Open',
        'progress' => 10,
        'milestone' => '1578453e53090b'
    ],
    [
        'id' => '15786dc7ccbea3',
        'status' => 'Open',
        'progress' => 20,
        'milestone' => '1578453e530943'
    ]
];

我需要获取按

progress
分组的
$tasks
数组中
milestone
值的总和,然后将这些总计存储/附加到
$milestones
数组。

所需输出:

[
    [
        'id' => '1578453e53090b',
        'milestone' => 'Wireframe',
        'assigned_to' => 9,
        'total' => 15
    ],
    [
        'id' => '1578453e530975',
        'milestone' => 'Development'
    ],
    [
        'id' => '1578453e530943',
        'milestone' => 'Design',
        'assigned_to' => 2,
        'total' => 20
    ]
]
php multidimensional-array sum mapping grouping
3个回答
2
投票

数组映射应该可以解决问题:

//will add 'progress' key to each milestone
$tabulate_progress = function($milestone) use ($tasks) {
    $milestone['progress'] = 0; //start with 0 progress

    foreach($tasks as $task):
        //add to progress if we find a matching task
        if($task['milestone']===$milestone['id'])
            $milestone['progress']+=$task['progress'];
    endforeach;

    return $milestone;
};
$milestones = array_map($tabulate_progress,$milestones);

这是一个演示


1
投票

执行此操作的方法之一是仅使用

foreach
。使用第一个
foreach
获取与
milestones
中的
foreach
匹配的 ID。

之后,使用一个简单的
tasks
容器继续使用,并使用一个简单的

milestone

将它们连接起来。


$total
    

使用嵌套循环方法的成本不必要地高——它只是在检查内循环中的匹配时执行了太多不必要的循环。

0
投票
if

数组执行一个循环,并声明对每一行的唯一引用。然后对

foreach($milestones as &$m) { // ^ add reference to make changes $total = 0; // initialize total holder foreach($tasks as $task) { if($task['milestone'] === $m['id']) { // if it matches $total += $task['progress']; // add } } $m['total'] = $total; // after its done, add another key pair being total and its value }

数组执行一次循环,将每个新遭遇的

$milestones
值添加到其映射/引用的行。
代码:(
演示

$tasks

此方法被认为是安全的,因为所有任务行都有一个
progress
值,该值与里程碑行

foreach ($milestones as &$row) { $ref[$row['id']] = &$row; } foreach ($tasks as ['milestone' => $m, 'progress' => $p]) { $ref[$m]['total'] = ($ref[$m]['total'] ?? 0) + $p; } var_export($milestones); 相关,并且里程碑数组中的所有

milestone
值都是唯一的。

    

© www.soinside.com 2019 - 2024. All rights reserved.