I have 2 arrays in the shape:
$langs = [
5 => "english",
10 => "french",
12 => "german"
...
];
Where the keys are the ids of the languages.
And:
$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,
],
...
];
Where the $posts
have the post in that language per day. When there weren’t any posts, there won’t be any entry in the array.
What I want is to process the posts array to have something like:
$result = [
[
"date" => "13-07-2022",
"english" => 90,
"french" => 34,
"german" => 0
],
[
"date" => "14-07-2022",
"english" => 6,
"french" => 0,
"german" => 0
],
...
];
This is, when there no posts from the "master" list of languages, I will set that language to 0.
I tried to iterate the $posts
and within it the langs
array in order to fill with zeros each new processed item, but I’m failing to fulfil it.
What I tried is:
$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;
My point is if there would be a better way to achieve this with no nested loop or more efficient way
3
Answers
If you loop through the posts array and for each item, first check if there is already a result for this date. If there isn’t – it adds the values from langs in using
array_fill_keys()
with a value of 0, and then adds the date in (you could make the date first by usingarray_merge()
).Then it always adds in the various keys…
$results = [];
which gives…
For putting the date first…
Output:
extract()
to generate convenient temporary variables for each iterationCode: (Demo)