在 php 中,我有一个关联行的索引数组,如下所示:
$the_array = [
['id' => 1, 'value' => 10, 'name' => 'apple'],
['id' => 1, 'value' => 20, 'name' => 'orange'],
['id' => 1, 'value' => 30, 'name' => 'banana'],
['id' => 2, 'value' => 100, 'name' => 'car'],
['id' => 2, 'value' => 200, 'name' => 'bicycle'],
];
我想通过对 id
值进行分组来重组它,并且在每个组中我想对 value
值求和并制作一个逗号分隔的 {{1} 字符串} 值。
name
这是我试过的:
[
['id' => 1, 'value' => 60, 'name' => 'apple,orange,banana'],
['id' => 2, 'value' => 300, 'name' => 'car,bicycle']
]
它不起作用,结果错误/不完整。
答案 0 :(得分:1)
我会创建一个中间数组,它首先按 id
分组为数组键,然后使用它来调用 array_column()
与 array_sum()
和 implode()
的组合来生成您的总和value
和组合的 name
字符串。
$temp_array = [];
foreach ($the_array as $init) {
// Initially, group them on the id key as sub-arrays
$temp_array[$init['id']][] = $init;
}
$result = [];
foreach ($temp_array as $id => $arr) {
// Loop once for each id ($temp_array has 2 elements from your sample)
// And add an element to $result
$result[] = [
'id' => $id,
// Sum the value subkeys
// array_column() returns just the key 'value' as an array
// array_sum() adds them
'value' => array_sum(array_column($arr, 'value')),
// implode the name subkeys into a string
'name' => implode(',', array_column($arr, 'name'))
];
}
print_r($result);
Array
(
[0] => Array
(
[id] => 1
[value] => 60
[name] => apple,orange,banana
)
[1] => Array
(
[id] => 2
[value] => 300
[name] => car,bicycle
)
)
答案 1 :(得分:1)
虽然已经回答了这个问题,但这里有另一种方法可以在一个循环中完成所有这些。
如果您跟踪将原始 ID 映射到其各自数组索引的小地图。
$result = [];
$map = [];
foreach ($the_array as $subarray) {
$id = $subarray['id'];
// First time we encounter the id thus we can safely push it into result
if (!key_exists($id, $map)) {
// array_push returns the number of elements
// since we push one at a time we can directly get the index.
$index = array_push($result, $subarray) - 1;
$map[$id] = $index;
continue;
}
// If the id is already present in our map we can simply
// update the running sum for the values and concat the
// product names.
$index = $map[$id];
$result[$index]['value'] += $subarray['value'];
$result[$index]['name'] .= ",{$subarray['name']}";
}
echo '<pre>';
print_r($result);
echo '</pre>';
结果:
Array
(
[0] => Array
(
[id] => 1
[value] => 60
[name] => apple,orange,banana
)
[1] => Array
(
[id] => 2
[value] => 300
[name] => car,bicycle
)
)
答案 2 :(得分:0)
没有必要编写多个循环或保留索引映射。最精简、直接的方法是根据分组的值使用临时的第一级键。
以下两个片段生成相同的输出并具有相同的内部处理。两个片段之间的唯一区别是,一个使用语言结构迭代输入数据,另一个使用函数迭代。
当您遍历数据时,根据每一行的 id
值将临时键应用于结果数组。如果第一次遇到给定的id
,则将整行数据存入组中。如果不是第一次遇到给定的 id
,则将 value
值添加到先前的 value
值并将新的 name
值连接到先前存储的 {{1} } 组中的值。
完成后,您可能希望通过调用 name
重新索引第一级。
经典array_values()
:(Demo)
foreach()
带有 $result = [];
foreach ($the_array as $row) {
if (!isset($result[$row['id']])) {
$result[$row['id']] = $row;
} else {
$result[$row['id']]['value'] += $row['value'];
$result[$row['id']]['name'] .= ",{$row['name']}";
}
}
var_export(array_values($result));
的函数式风格:(Demo)
array_reduce()