PHP数组,当值通过开始和结束键更改为新数组时拆分数组

时间:2012-03-19 14:17:11

标签: php arrays

我正在寻找处理这个日期数组和一个基本上是布尔值的单值:

Array (
    [20120401] => 1
    [20120402] => 1
    [20120403] => 1
    [20120404] => 0
    [20120405] => 0
    [20120406] => 0
    [20120407] => 1
    [20120408] => 1
    [20120409] => 1
)

进入这个:

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'
        ),
)

因此,当值发生变化时,基本上会拆分数组,并创建一个新数组,其中包含值的更改位置的开始键和结束键以及该部分的值。很抱歉,如果解释没有示例阵列那么有意义!

对我而言,似乎一个递归函数可能适合于第一个示例数组值在处理时被删除,并且使用缩短的数组再次调用该函数。虽然我可能会遗漏一些简单的东西!

谢谢!

编辑:

为了更新这一点,我应该更清楚地说明原始数组将跨越月份分区,因此我更新了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'] );
}

2 个答案:

答案 0 :(得分:2)

只需在数组中循环一次即可完成此操作:创建一个存储前一个键的变量(基本上将当前键存储在循环的循环结束时),然后将其与新键进行比较。

这样的事情:

foreach ($array as $key => $value)
{
   if ($key != $prev_key)
      // append relevant value to the new array here

   $prev_key = $key;
}

答案 1 :(得分:0)

不需要递归,因为您可以迭代地解决这个问题。除非条件匹配以创建新元素,否则构建当前元素。诀窍是使第一个当前元素默认无效,因此第一个条目将创建一个新元素:

$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
        )

)

除了这里编号的命名键外,这就是你要找的东西。