我想处理这个日期数组和一个本质上布尔的单一值:
阵列([20124001]=>1[20124002]=>1[20124043]=>1[20124044]=>0[20124005]=>0[20124006]=>0[20124007]=>1[20124048]=>1[20124009]=>1)
进入:
阵列(阵列('start_date'=>'20120401','end_date'=>'20120403',"status"=>"1"),阵列('start_date'=>'20120404','end_date'=>'20120406',"status"=>"0"),数组('start_date'=>'20120407','end_date'=>'20120409',"status"=>"1"),)
因此,本质上是在值更改时拆分数组,并创建一个新数组,其中包含值更改位置的开始键和结束键以及该部分的值。很抱歉,如果解释没有示例数组那么有意义!
在我看来,从表面上看,递归函数可能适合第一个示例数组的值在处理时被删除,然后用缩短的数组再次调用该函数。不过,我可能会错过一些简单的东西!
谢谢!
编辑:
为了更新这一点,我应该在问题中更清楚地表明,原始数组将跨越月份划分,因此我更新了hakre提供的代码以考虑到这一点。我还修改了它以使用所需的输出数组键。在我的情况下,我确实可以控制输入数组,因此可以在传递日期之前验证日期。再次感谢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'] );
}
您只需在数组中使用一个循环即可完成此操作:创建一个存储上一个键的变量(基本上是在循环结束时存储当前键),然后将其与新键进行比较。
类似这样的东西:
foreach ($array as $key => $value)
{
if ($key != $prev_key)
// append relevant value to the new array here
$prev_key = $key;
}
不需要递归,因为您可以迭代求解。除非符合创建新元素的条件,否则将构建当前元素。诀窍是默认情况下使第一个当前元素无效,因此第一个条目将创建一个新元素:
$output = array();
$current = array();
foreach($input as $date => $status) {
if (!$current || $current[2] != $status || $current[1] != $date-1) {
unset($current);
$current = array($date, $date, $status);
$output[] = &$current;
continue;
}
$current[1] = $date;
}
unset($current);
这将为$output
提供以下结果:
Array
(
[0] => Array
(
[0] => 20120401
[1] => 20120403
[2] => 1
)
[1] => Array
(
[0] => 20120404
[1] => 20120406
[2] => 0
)
[2] => Array
(
[0] => 20120407
[1] => 20120409
[2] => 1
)
)
除了这里编号的命名密钥外,这就是您要查找的。