Search code examples
phparraysloopsmissing-datadefault-value

Fill 2d array with rows for missing periods of array


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

Solution

  • 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