Avión
Avión

Reputation: 8376

Filling in array in PHP with missing years in ascending order

Having the following array of arrays:

array(2) {
  [0]=>
  array(4) {
    [0]=>
    array(2) {
      [0]=>
      string(4) "2012"
      [1]=>
      float(1)
    }
    [1]=>
    array(2) {
      [0]=>
      string(4) "2013"
      [1]=>
      float(1)
    }
    [2]=>
    array(2) {
      [0]=>
      string(4) "2014"
      [1]=>
      float(2)
    }
    [3]=>
    array(2) {
      [0]=>
      string(4) "2015"
      [1]=>
      float(1)
    }
  }
  [1]=>
  array(7) {
    [0]=>
    array(2) {
      [0]=>
      string(4) "2008"
      [1]=>
      float(2)
    }
    [1]=>
    array(2) {
      [0]=>
      string(4) "2009"
      [1]=>
      float(7)
    }
    [2]=>
    array(2) {
      [0]=>
      string(4) "2010"
      [1]=>
      float(2)
    }
    [3]=>
    array(2) {
      [0]=>
      string(4) "2011"
      [1]=>
      float(2)
    } // <---------------------------- HERE I MISS YEAR 2012
    [4]=>
    array(2) {
      [0]=>
      string(4) "2013"
      [1]=>
      float(19)
    }
    [5]=>
    array(2) {
      [0]=>
      string(4) "2014"
      [1]=>
      float(8)
    }
    [6]=>
    array(2) {
      [0]=>
      string(4) "2015"
      [1]=>
      float(8)
    }
  }
}

The first array is correct as it has the order year ascending order, 2012, 2013, 2014 and 2015. The second array has the issue as you can see it misses the year 2012.

I want to fill all the missing years in ascending order (and add a float 0), in the example would be to push the value 2012 into the array (the second array), with a float value of 0.

   array(2) {
      [0]=>
      string(4) "2012"
      [1]=>
      float(0)
    }

So my desired output would be:

array(2) {
  [0]=>
  array(4) {
    [0]=>
    array(2) {
      [0]=>
      string(4) "2012"
      [1]=>
      float(1)
    }
    [1]=>
    array(2) {
      [0]=>
      string(4) "2013"
      [1]=>
      float(1)
    }
    [2]=>
    array(2) {
      [0]=>
      string(4) "2014"
      [1]=>
      float(2)
    }
    [3]=>
    array(2) {
      [0]=>
      string(4) "2015"
      [1]=>
      float(1)
    }
  }
  [1]=>
  array(7) {
    [0]=>
    array(2) {
      [0]=>
      string(4) "2008"
      [1]=>
      float(2)
    }
    [1]=>
    array(2) {
      [0]=>
      string(4) "2009"
      [1]=>
      float(7)
    }
    [2]=>
    array(2) {
      [0]=>
      string(4) "2010"
      [1]=>
      float(2)
    }
    [3]=>
    array(2) {
      [0]=>
      string(4) "2011"
      [1]=>
      float(2)
    }
    [4]=>
    array(2) {
      [0]=>
      string(4) "2012"
      [1]=>
      float(0)
    }
    [5]=>
    array(2) {
      [0]=>
      string(4) "2013"
      [1]=>
      float(19)
    }
    [6]=>
    array(2) {
      [0]=>
      string(4) "2014"
      [1]=>
      float(8)
    }
    [7]=>
    array(2) {
      [0]=>
      string(4) "2015"
      [1]=>
      float(8)
    }
  }
}

Note that this is an 'easy' example as it only misses one year, but I would like to have a 'general' script that can fix it doing the same; filling the missed year in ascending order and putting the float to 0.

2008, 2009, 2013, 2014, to fill 2008, 2009, 2010,. 2011, 2012, 2013, 2014.

This is my try, being arraySeries the name of the array. I'm stucked on the part I've to make the changes.

foreach ($arraySeries as $value) {
    $i = 0;
    foreach ($value as $innerArray) {
        if ($i == 0) {
                $firstYear = $innerArray[0];
            }
        $year = $innerArray[0];
        if ($year == $firstYear) {
            echo "It's the same year, ok";
        } else {
            echo "Missing year! - Fill value";
            // Do stuff
        }
        var_dump($year);
        $i++;
        $firstYear++;
    }
    echo "<br>";
    $firstYear = null;
}

Any other more elegant / better performance solutions are welcome.

PS: I'm using PHP 5.2 (it's not my machine and I cant update the version)

Thanks in advance.

Upvotes: 1

Views: 152

Answers (1)

Kevin
Kevin

Reputation: 41885

First thing to pop out of my mind is just to get the years provided from data (with the missing year).

Then, get the minimum and maximum of it, create a complete year range.

Compare the collected data so that you'll know the missing year. After that is straight forward, add the missing year, then the usual sorting:

foreach($array as &$first) {
    $years = array_map('reset', $first); // get all years first
    $min = min($years); // min and max
    $max = max($years);
    $year_range = range($min, $max); // create complete years
    $missing_years = array_diff($year_range, $years); // compare both all years to complete range to get the missing
    foreach($missing_years as $y) {
        $first[] = [$y, (float) 0]; // push missing year
    }
    // sort by date
    usort($first, function($a, $b){
        return $a[0] - $b[0];
    });
}

Note: If your PHP can't support anonymous functions, just create a simple function outside and use it in usort.

Upvotes: 2

Related Questions