2011-01-07 76 views
4

您是否曾經有過這樣一段時間,您的大腦剛剛沒有擺脫一檔?基於重疊實體陣列創建一個新陣列

我有一個包含開始和結束時間的數組。我想創建一個新的數組,顯示初始數組中重疊條目的鍵。所以說,我們有一些「保留」。任何重疊的「保留」屬於同一個「會話」。象最初的數組:

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

什麼是爲大型陣列做到這一點的最有效方法是什麼?謝謝!

+0

其實我覺得有點嫉妒,你必須得解決這個:)我說你應該保持的軌道每個會話的開始時間和結束時間,以及每次預約檢查它屬於哪個會話。如果它屬於一個會話,則更新其開始和/或結束時間。如果不是,請創建一個新會話。如果它屬於多個會話,則合併會話。快樂的編碼! – 2011-01-07 13:07:31

+0

*「任何重疊的'保留'屬於同一'會話'。」* - 這不是100%清楚。所有的預訂都必須重疊配對嗎? 10:00-11:00,10:30-11:30和11:15-12:00形成一個會話(最後一個與第一個不重疊)? – 2011-01-07 13:15:34

+0

謝謝拉法爾 - 我已經對這個示例數組表示了讚賞,在這種情況下,上述三個保留實際上是重疊的,因爲第一個和最後一個保留與中間保留相交。同樣,如果預訂在12:30結束,另一個預定在12:30開始,它們也可以被認爲是重疊的。 – boatingcow 2011-01-07 13:37:13

回答

3

對於每個保留,將它的(start,id)和(end,id)(分別)放入一個按照第一項(即時間)排序的元組數組中。然後從最低時間到最高值遍歷數組,什麼保留是開放的,把每個新的一個放在同一個會話中。一旦會話中的最後一次預定關閉,關閉會話。

0

不是真正的代碼,因此沒有測試,但可能是一個辦法:

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 

    } 
}