I’m looking to process this array of dates and an essentially boolean single value:
Array (
[20120401] => 1
[20120402] => 1
[20120403] => 1
[20120404] => 0
[20120405] => 0
[20120406] => 0
[20120407] => 1
[20120408] => 1
[20120409] => 1
)
Into this:
Array (
Array(
'start_date' => '20120401',
'end_date' => '20120403',
'status' => '1'
),
Array(
'start_date' => '20120404',
'end_date' => '20120406',
'status' => '0'
),
Array('start_date' => '20120407',
'end_date' => '20120409',
'status' => '1'
),
)
So essentially splitting the array when the value changes and creating a new array with the start key and end key of where the value changed and the value of that section. Sorry if the explanation doesn’t make as much sense as the example arrays!
It seems on the face of it to me perhaps a recursive function would suit whereby the 1st example arrays values get removed when processed and the function is called again with the shortened array. I could be missing something simple with this though!
Thanks!
EDIT:
Just to update this, I should have made it clearer in the question that the original array will span month divisions so I updated the code provided by hakre to take account of this. I also modified it to use the desired output array keys. In my case I do have control of the input array so can validate the dates before being passed. Thanks again hakre.
//set the time period in seconds to compare, daily in this case
$time_period = (60 * 60 * 24);
$output = array();
$current = array();
foreach($input as $date => $state) {
//convert date to UTC
$date = strtotime($date);
if (!$current || $current['state'] != $state ||
$current['to'] != $date - $time_period) {
unset($current);
$current = array('state' => $state, 'from' => $date, 'to' => $date);
$output[] = &$current;
continue;
}
$current['to'] = $date;
}
unset($current);
// convert date back to the desired format
foreach ( $output as $index => $section ) {
$output[$index]['from'] = date("Ymd", $output[$index]['from'] );
$output[$index]['to'] = date("Ymd", $output[$index]['to'] );
}
There is no need for recursion because you can solve this iteratively. You build the current element unless the conditions are matched to create a new element. The trick is to make the first current element invalid per default, so the first entry will create a new one:
Which will give you the following result for
$output:Apart from the named keys which are numbered here, this is what you’re looking for.