我正在尝试对二维数组中的数据进行分组,同时利用查找数组来确保每个组中都存在默认值。
我的查找/映射数组将语言 ID 与语言名称相关联。
$langs = [
5 => "english",
10 => "french",
12 => "german"
...
];
另一个数组保存应按日期值分组的数据。
$posts = [
[
"date" => "13-07-2022",
"lang_id" => 5,
"amount" => 90,
],
[
"date" => "13-07-2022",
"lang_id" => 10,
"amount" => 34,
],
[
"date" => "14-07-2022",
"lang_id" => 5,
"amount" => 7,
],
...
];
$posts
每天都有该语言的帖子。当没有任何帖子时,数组中不会有任何条目。
我想重构数据以按日期分组,每个子数组应包含日期和累积的关联语言量:
$result = [
[
"date" => "13-07-2022",
"english" => 90,
"french" => 34,
"german" => 0
],
[
"date" => "14-07-2022",
"english" => 6,
"french" => 0,
"german" => 0
],
...
];
这是,当“主”语言列表中没有帖子时,我会将该语言设置为 0。
我尝试迭代
$posts
及其中的 langs
数组,以便用零填充每个新处理的项目,但我未能实现它。
我尝试的是:
$d = $post[0]['date'];
$result = [];
foreach ($posts as $post) {
if ($d != $post['date']) {
$d = $post['date'];
$result[] = $proc;
$proc = [];
$proc['date'] = $d;
}
foreach ($langs as $id => $name) {
if ($id == $post['lang_id']) {
$proc[$name] = $post['amount'];
} elseif (!isset($proc[$name])) {
$proc[$name] = 0;
}
}
}
$result[] = $proc;
我的观点是是否有更好的方法来实现这一目标,无需嵌套循环或更有效的方法
如果循环遍历 posts 数组并针对每个项目,首先检查是否已经有该日期的结果。如果没有 - 它会使用
array_fill_keys()
添加 langs 中的值,值为 0,然后添加日期(您可以先使用 array_merge()
创建日期)。
然后它总是添加各种键...
$结果=[];
foreach ($posts as $post) {
if (array_key_exists($post['date'], $results) == false) {
$results[$post['date']] = array_fill_keys($langs, 0);
$results[$post['date']]['date'] = $post['date'];
}
$results[$post['date']][$langs[$post['lang_id']]] = $post['amount'];
}
var_dump(array_values($results));
这给出了...
array(2) {
[0] =>
array(4) {
'english' =>
int(90)
'french' =>
int(34)
'german' =>
int(0)
'date' =>
string(10) "13-07-2022"
}
[1] =>
array(4) {
'english' =>
int(7)
'french' =>
int(0)
'german' =>
int(0)
'date' =>
string(10) "14-07-2022"
}
}
把日期放在第一位...
$results[$post['date']] = array_merge(['date' => $post['date']], array_fill_keys($langs, 0));
$langs = [
5 => 'english',
10 => 'french',
12 => 'german',
];
$posts = [
[ 'date' => '13-07-2022', 'lang_id' => 5, 'amount' => 90, ],
[ 'date' => '13-07-2022', 'lang_id' => 10, 'amount' => 34, ],
[ 'date' => '14-07-2022', 'lang_id' => 5, 'amount' => 7, ],
];
$langs_template = array_combine($langs, array_fill(0, count($langs), 0));
$result =
array_values(
array_reduce(
$posts,
function ($carry, $item) use ($langs, $langs_template) {
$date = $item['date'];
if (!array_key_exists($date, $carry)) {
$carry[$date] = [ 'date' => $date, ...$langs_template ];
}
$carry[$date][$langs[$item['lang_id']]] = $item['amount'];
return $carry;
},
[]
)
);
print_r($result);
输出:
Array
(
[0] => Array
(
[date] => 13-07-2022
[english] => 90
[french] => 34
[german] => 0
)
[1] => Array
(
[date] => 14-07-2022
[english] => 7
[french] => 0
[german] => 0
)
)
extract()
为每次迭代生成方便的临时变量代码:(演示)
$defaults = array_fill_keys($langs, 0);
$result = [];
foreach ($posts as $row) {
extract($row);
$result[$date] ??= ['date' => $date] + $defaults;
$result[$date][$langs[$lang_id]] += $amount;
}
var_export(array_values($result));
为了避免在循环后重新索引结果,请将引用推入结果中。 演示
$defaults = array_fill_keys($langs, 0);
$result = [];
foreach ($posts as $row) {
extract($row);
if (!isset($ref[$date])) {
$ref[$date] = ['date' => $date] + $defaults;
$result[] = &$ref[$date];
}
$ref[$date][$langs[$lang_id]] += $amount;
}
var_export($result);