Php 基于重叠实体数组创建新数组

Php 基于重叠实体数组创建新数组,php,arrays,algorithm,performance,Php,Arrays,Algorithm,Performance,你是否曾经有过这样的一天,你的大脑无法脱离1档 我有一个包含开始和结束时间的数组。我想创建一个新数组,显示初始数组中重叠项的键。所以,假设我们有一些“保留”。任何重叠的“保留”都属于同一个“会话”。初始数组,如: [reservations] => Array ( [1125] => Array ( [start] => 2011-01-07 10:00:00 [en

你是否曾经有过这样的一天,你的大脑无法脱离1档

我有一个包含开始和结束时间的数组。我想创建一个新数组,显示初始数组中重叠项的键。所以,假设我们有一些“保留”。任何重叠的“保留”都属于同一个“会话”。初始数组,如:

[reservations] => Array
    (
        [1125] => Array
            (
                [start] => 2011-01-07 10:00:00
                [end] => 2011-01-07 10:30:00
            )
        [1244] => Array
            (
                [start] => 2011-01-07 10:15:00
                [end] => 2011-01-07 11:30:00
             )
        [1311] => Array
            (
                [start] => 2011-01-07 11:00:00
                [end] => 2011-01-07 11:45:00
            )
        [1422] => Array
            (
                [start] => 2011-01-07 12:00:00
                [end] => 2011-01-07 12:30:00
             )
        [1561] => Array
            (
               [start] => 2011-01-07 12:30:00
               [end] => 2011-01-07 12:45:00
            )
        [1622] => Array
            (
               [start] => 2011-01-07 13:00:00
               [end] => 2011-01-07 13:45:00
            )
    )
[sessions] => Array
    (
        [0] => Array
            (
                [0] => 1125
                [1] => 1244
                [2] => 1311
            )
        [1] => Array
            (
                [0] => 1422
                [1] => 1561
            )
        [2] => Array
            (
                [0] => 1622
            )
    )
将生成一个新数组,如:

[reservations] => Array
    (
        [1125] => Array
            (
                [start] => 2011-01-07 10:00:00
                [end] => 2011-01-07 10:30:00
            )
        [1244] => Array
            (
                [start] => 2011-01-07 10:15:00
                [end] => 2011-01-07 11:30:00
             )
        [1311] => Array
            (
                [start] => 2011-01-07 11:00:00
                [end] => 2011-01-07 11:45:00
            )
        [1422] => Array
            (
                [start] => 2011-01-07 12:00:00
                [end] => 2011-01-07 12:30:00
             )
        [1561] => Array
            (
               [start] => 2011-01-07 12:30:00
               [end] => 2011-01-07 12:45:00
            )
        [1622] => Array
            (
               [start] => 2011-01-07 13:00:00
               [end] => 2011-01-07 13:45:00
            )
    )
[sessions] => Array
    (
        [0] => Array
            (
                [0] => 1125
                [1] => 1244
                [2] => 1311
            )
        [1] => Array
            (
                [0] => 1422
                [1] => 1561
            )
        [2] => Array
            (
                [0] => 1622
            )
    )

对于大型阵列,最有效的方法是什么?谢谢

对于每个保留,将其(开始,id)和(结束,id)(分别)放入按第一项(即时间)排序的元组数组中,然后从最低时间到最高时间遍历该数组,保持保留打开,将每个新的保留放在同一会话中。会话中的最后一个保留关闭后,请关闭会话

不是真正的代码,因此未经测试,但可能是一种方式:

foreach([reservations] as $key => $res){
    $a[ timestamp_of( $res[start] ) ] = $key;
    $a[ timestamp_of( $res[end] ) ] = $key;
}

ksort($a, SORT_NUMERIC);  //sort by timestamp

$open = Array();   //currently 'open' reservations while looping through
$sesions = Array();    //result array for sessions
$active = 0;    //ID of active session

foreach($a as $item){
    if($item in $open) {    //check if current reservation is in list of open ones

        strip($item, $open);    //if so: close it → remove from array
        if( sizeof( $open ) == 0 ) $active++;   //if no reservations open, close the session

    } else {     //if current reservation is not open...

        $open[$item] = true;    //open it
        $sessions[$active][] = $item    //and add it to current session

    }
}

事实上,我有点嫉妒你必须解决这个问题:)我想说你应该跟踪每个会话的开始时间和结束时间,以及每个预约检查它属于哪个会话。如果它属于会话,请更新其开始和/或结束时间。如果没有,请创建一个新会话。如果它属于多个会话,请合并会话。快乐编码!“任何重叠的‘保留’都属于同一个‘会话’。”-这不是100%清楚。所有预订都必须成对重叠吗?10:00-11:00、10:30-11:30和11:15-12:00是否构成一个会话(最后一个与第一个不重叠)?感谢Rafal-我已经对示例数组进行了扩充,以表明在本例中,是的,上面的三个保留实际上是重叠的,因为第一个和最后一个保留与中间的保留相交。同样,如果一个预订在12:30结束,另一个预订在12:30开始,它们也可以被视为重叠。这正是我要解释的解决方案。;-)我已将此标记为答案,因为它与我们使用的最接近<代码>k排序($a,排序\u数字)
asort
按保留键的值排序,而
ksort
按键排序。