Reputation: 532
I want to fill missing months in an array with zeros.
Input Data:
$d = [
[
'type' => 25500,
'month' => 'July'
],
[
'type' => 5465,
'month' => 'January'
],
[
'type' => 40000,
'month' => 'April'
],
[
'type' => 35000,
'month' => 'June'
],
[
'type' => 10000,
'month' => 'February'
]
];
$allmonths = ['January','February','March', 'April','May','June','July','August','September','October','November','December'];
My Code:
$res = [];
foreach ($allmonths as $key => $mes) {
$teste = array_search($mes, array_column($d, 'month'));
if ($teste) {
$res[$teste] = ['type' => 2, 'moth '=> $mes];
} else {
$res[] = ['type' => 0,'moth '=> $mes];
}
}
I have been trying to solve this problem but with no success.
Expected Result:
Array
(
[0] => Array
(
[type] => 25500
[month] => July
)
[1] => Array
(
[type] => 5465
[month] => January
)
[2] => Array
(
[type] => 40000
[month] => April
)
[3] => Array
(
[type] => 35000
[month] => June
)
[4] => Array
(
[type] => 10000
[month] => February
)
[5] => Array
(
[type] => 0
[month] => March
)
[6] => Array
(
[type] => 0
[month] => May
)
[7] => Array
(
[type] => 0
[month] => August
)
[8] => Array
(
[type] => 0
[month] => September
)
[9] => Array
(
[type] => 0
[month] => October
)
[10] => Array
(
[type] => 0
[month] => November
)
[11] => Array
(
[type] => 0
[month] => December
)
)
Upvotes: 1
Views: 353
Reputation: 48031
This answer goes to the extra effort of putting the months in order (not that you requested it -- it just feels right to me).
Also, efficiency is probably not a focal point for this task, but for researchers' benefit I'll express that in_array()
, array_search()
, array_diff()
, and any other "value comparing" technique are not able to work as efficiently as "key comparing" techniques such as array_key_exists()
, isset()
, ??
(null coalescing operator), array_diff_key()
, etc. For this reason, I favor endeavor's first snippet -- !isset()
will perform very well within a loop.
Here is my alternative which makes no iterated function calls (but does iterate the full array of months). (Demo)
$lookup = array_column($d, null, 'month'); // assign temporary keys for improved efficiency
$result = [];
foreach ($allmonths as $month) {
$result[] = $lookup[$month] ?? ['type' => 0, 'month' => $month];
}
var_export($result);
Upvotes: 1
Reputation: 72269
I will go with array_column(), array_diff() and a single foreach()
Process:
1)Create an array of all months
2)Get all month present in your array using array_column()
.
3)Find the not available months in your array using array_diff()
.
4)Iterate over this difference and add them to your current array.
$allMonths = ['January','February','March', 'April','May','June','July','August','September','October','November','December'];
$currentMonths = array_column($d, 'month');
$notIncludedMonth = array_diff($allMonths,$currentMonths);
foreach ($notIncludedMonth as $month) {
$d[] = [
'type' => 0,
'month' => $month,
];
}
print_r($d);
Output : https://3v4l.org/GsFoO
Upvotes: 3
Reputation: 619
Since the objective here is to append missing months to the original array $d
without changing the existing elements
(as per the expected result), we can simply change $d
instead of creating a new variable $res
.
Also converting the keys of the array $d
will make it much easier to work with. This does assume that month
appears only once in $d
.
## Assumption: Month is unique
$dNew = array_column($d, null, 'month');
$res = [];
foreach ($allmonths as $key => $mes) {
if (!isset($dNew[$mes])) {
$d[] = ['type' => 0, 'moth ' => $mes];
}
}
var_dump($d);
If month
is not unique in the array you can use array_search
or in_array
to get similar results.
$dNew = array_column($d, 'month');
$res = [];
foreach ($allmonths as $key => $mes) {
if (!array_search($mes, $dNew)) {
$d[] = ['type' => 0, 'moth ' => $mes];
}
}
print_r($d);
Upvotes: 1
Reputation: 1881
Something like this could work:
<?php
$d = [
[
'type' => 25500,
'month' => 'July'
],
[
'type' => 5465,
'month' => 'January'
],
[
'type' => 40000,
'month' => 'April'
],
[
'type' => 35000,
'month' => 'June'
],
[
'type' => 10000,
'month' => 'February'
]
];
$allmonths = ['January','February','March', 'April','May','June','July','August','September','October','November','December'];
$present_months = array_column($d, 'month');
foreach ($allmonths as $month) {
if (!in_array($month, $present_months)) {
$d[] = [
'type' => 0,
'month' => $month,
];
}
}
var_dump($d);
Upvotes: 2