# Dynamic array of Years

I wanted to make a dynamic select statement from this year to 10 years. This gets the job done, but I feel like it's a little much.

 form_dropdown('year', array_combine(range(date('Y'), date('Y')+10), range(date('Y'), date('Y')+10)), set_value('year'));


Specifically, is there a better way to create this array, other than this?

array_combine(range(date('Y'), date('Y')+10), range(date('Y'), date('Y')+10))


Desired output (at least for this year):

Array
(
[2014] => 2014
[2015] => 2015
[2016] => 2016
[2017] => 2017
[2018] => 2018
[2019] => 2019
[2020] => 2020
[2021] => 2021
[2022] => 2022
[2023] => 2023
[2024] => 2024
)


In order to get the output that you wanted, using array_combine will most likely be your best bet. You can simplify your statements pretty easily because variables are you friends:

$current_year = date('Y');$date_range = range($current_year,$current_year+10);

form_dropdown('year', array_combine($date_range,$date_range), set_value('year'));


I think this solves what I thought to be a problem, the combining of so many functions. I ended up simplifying it a little more.

$current_year = date('Y');$range = range($current_year,$current_year+10);
$years = array_combine($range, $range);  • I apologize for adding to your answer, but found writing that as a comment would have been absurd. – Brett Santore Jul 1 '14 at 17:04 (I'm leaving the original answer intact for posterity, but please read the edit at the bottom of the answer as the answer is wrong). Why create a complicated line of code, such as: array_combine(range(date('Y'), date('Y')+10), range(date('Y'), date('Y')+10))  When you can do a simple for-loop, such as: $current_year = date('Y');
$max_year =$current_year + 10;
for($i =$current_year; $i <=$max_year; $i++){$year_array[$i] =$i;
}


Well - speed. The one liner mixture of array_combine(), range() and date() is multiple times faster than the for-loop. Not to mention that it creates less work for the GC.

I ran the two pieces of code above and this was the output:

$start_0 = microtime();$year_array = array_combine(range(date('Y'), date('Y')+10), range(date('Y'), date('Y')+10));
$end_0 = microtime();$start_1 = microtime(true);
$current_year = date('Y');$max_year = $current_year + 10;$year_array = array();
for($i =$current_year; $i <=$max_year; $i++){$year_array[$i] =$i;
}
$end_1 = microtime(true); echo "<pre>"; print_r($year_array);
echo "0 Time: " . ($end_0 -$start_0) . "<br>";
echo "1 Time: " . ($end_1 -$start_1) . "<br>";
echo "</pre>";


Now, even if we make use of inlining the function calls, it gets even worse! See:

$start_0 = microtime();$year_array = array_combine(range(date('Y'), date('Y')+10), range(date('Y'), date('Y')+10));
$end_0 = microtime();$start_1 = microtime(true);
$year_array = array(); for($i = date('Y'); $i <= date('Y') + 10;$i++){
$year_array[$i] = $i; }$end_1 = microtime(true);

echo "<pre>";
print_r($year_array); echo "0 Time: " . ($end_0 - $start_0) . "<br>"; echo "1 Time: " . ($end_1 - $start_1) . "<br>"; echo "</pre>";  So, the best option is to go the array_combine(), range(), date() route. However, we can further optimize it as: $start_range = date('Y');
$range = range($start_range, $start_range + 10) array_combine($range, $range)  That way, we end up with 2 function calls to date(), range() and 2 new variables (which are cheaper than a function call), but is still not as performant as your original one liner. $start_0 = microtime();
$year_array = array_combine(range(date('Y'), date('Y')+10), range(date('Y'),, date('Y')+10));$end_0 = microtime();

$start_1 = microtime(true);$year_array = array();
for($i = date('Y');$i <= date('Y') + 10; $i++){$year_array[$i] =$i;
}
$end_1 = microtime(true);$start_2 = microtime(true);
$start_range = date('Y');$range = range($start_range,$start_range + 10);
array_combine($range,$range);
$end_2 = microtime(true); echo "<pre>"; print_r($year_array);
echo "0 Time: " . ($end_0 -$start_0) . "<br>";
echo "1 Time: " . ($end_1 -$start_1) . "<br>";
echo "2 Time: " . ($end_2 -$start_2) . "<br>";
echo "</pre>";


My recommendation would be to keep your one liner.

EDIT: My recommendation is you do #2 as I missed microtime(true) on $start_0 and $end_0, thus I completely misread the benchmark output (which would make the one liner the slowest of the three tests). Thank you for catching that @Brett Santore.

• It appears you ran test 0 without microtime(true), with 1.09E-5 or (0.0000109) < .0001. Wouldn't that support test 2 being faster with only 3 function calls? – Brett Santore Jul 1 '14 at 17:20
• Ah drats. Yeah, you're right. Tests 1 and 2 are increasingly faster by a near 10x magnitude: i.imgur.com/JZEi3PY.png – jsanc623 Jul 1 '14 at 17:40
• Fantastic contribution – Brett Santore Jul 1 '14 at 17:42
• I added an edit at the top and bottom clarifying the incorrectness of the answer. I also left the original answer intact for posterity. – jsanc623 Jul 1 '14 at 17:43