Reputation: 846
I have an array that contains periods from 1 - 13. Sometimes the array doesn't contain data for all periods and I need to fill in the missing ones, for example:
$array = [
['period' => 7, 'y' => 20],
['period' => 8, 'y' => 20.50],
['period' => 9, 'y' => 7020],
['period' => 10, 'y' => 6520],
['period' => 11, 'y' => 65920],
['period' => 12, 'y' => 62820],
['period' => 13, 'y' => 6120],
];
For this case I need to run a php loop to fill in the missing first 6 periods with 0
y
values. I've tried a variety of loops but with no joy.
Desired output:
[
['period' => 1, 'y' => 0],
['period' => 2, 'y' => 0],
['period' => 3, 'y' => 0],
['period' => 4, 'y' => 0],
['period' => 5, 'y' => 0],
['period' => 6, 'y' => 0],
['period' => 7, 'y' => 20],
['period' => 8, 'y' => 20.50],
['period' => 9, 'y' => 7020],
['period' => 10, 'y' => 6520],
['period' => 11, 'y' => 65920],
['period' => 12, 'y' => 62820],
['period' => 13, 'y' => 6120],
]
Upvotes: 1
Views: 82
Reputation: 48031
Use array_column()
to generate a lookup array from your input array -- effectively applying associative, numeric, first-level keys without disturbing the original row data.
Then iterate from 1 to 13. If the current iteration's integer is found in the lookup, then push the found row; otherwise push the default row containing the incremented value.
Code: (Demo)
$lookup = array_column($data, null, 'period');
$result = [];
for ($i = 1; $i <= 13; ++$i) {
$result[] = $lookup[$i] ?? ['period' => $i, 'y' => 0];
}
var_export($result);
Upvotes: 0
Reputation: 673
Assuming your $array
is sorted by period
.
You can create a new array that copies the content or your $array
and set a new content for missing periods.
$new_array = [];
for ($i = 1, $j = 0; $i <= 13; $i++) {
if ($array[$j]['period'] == $i) {
$new_array[] = $array[$j]; //copy contents
$j++;
} else {
$new_array[] = [ 'period' => $i, 'y' => 0 ]; // set new contents
}
}
Upvotes: 0
Reputation: 54659
You can get good semantics with using the standard array methods. For example:
<?php
$in = [
['period' => 7, 'y' => 20],
['period' => 8, 'y' => 20.50],
['period' => 9, 'y' => 7020],
['period' => 10, 'y' => 6520],
['period' => 11, 'y' => 65920],
['period' => 12, 'y' => 62820],
['period' => 13, 'y' => 6120],
];
// collect available periods
$available = array_column($in, 'period');
// calculate missing periods
$missing = array_diff(range(1, 13), $available);
// transform missing to correct format
$addition = array_map(function ($period) { return ['period' => $period, 'y' => 0]; }, $missing);
// add missing to input
$out = array_merge($in, $addition);
// sort by period
usort($out, function ($a, $b) {
return $a['period'] <=> $b['period'];
});
// done
print_r($out);
demo: https://3v4l.org/2fDYW
Upvotes: 3
Reputation: 392
This should solve your problem:
Let's say $p_array is your array that contains periods from 1 - 13.
// get all periods number that is not missed
$not_missed_periods = array();
foreach ($p_array as $p_each)
{
$not_missed_periods[] = $p_each['period'];
}
// loop for checking all valid periods i.e 1-13
for ($i=1; $i<=13; $i++)
{
// check if $i OR period is not in $not_missed_periods
if (!in_array($i, $not_missed_periods)) {
$p_array[] = array('period' => $i, 'y' => 0);
}
}
print_r($p_array);
Upvotes: 0
Reputation: 4806
You can try this
for ($i=1 $<=13, $i++) {
$exits = false;
foreach ($array as $key => $value) {
if ($value['period'] == $key) {
$exits = true;
}
}
if ($exits) {
$array[] = ['period' => $i , 'y' => 0];
}
}
Upvotes: 0
Reputation: 139
start by filling the whole array you need with all period with a value of 0.
Then for each period you get in your data array, use the period id to update the value of period in the right place in the array.
Hope it helps...
Upvotes: 0