1

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],
]
0

6 Answers 6

3

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

Sign up to request clarification or add additional context in comments.

Comments

0

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...

Comments

0

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];
   }
}

Comments

0

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);

Comments

0

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
    }
}

Comments

0

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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.