我需要对一个数组中由另一列分组的一列值求和,并根据特定列值将这些结果映射到另一个数组。
示例输入:
$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
]
]
数组映射应该可以解决问题:
//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);
执行此操作的方法之一是仅使用
foreach
。使用第一个 foreach
获取与 milestones
中的 foreach
匹配的 ID。之后,使用一个简单的
tasks
容器继续使用,并使用一个简单的milestone
将它们连接起来。
$total
使用嵌套循环方法的成本不必要地高——它只是在检查内循环中的匹配时执行了太多不必要的循环。
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
值添加到其映射/引用的行。代码:(演示) 此方法被认为是安全的,因为所有任务行都有一个
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
值都是唯一的。