PHP数组,当值更改为带有开始键和结束键的新数组时,拆分数组


PHP Arrays, split array when value changes into new array with start and end keys

我想处理这个日期数组和一个本质上布尔的单一值:

阵列([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
        )
)

除了这里编号的命名密钥外,这就是您要查找的。