2011-09-27 77 views
3

我有查詢(對於MongoDB數據庫),它返回的對象已被映射減少,對象每15分鐘報告一次,但問題是,如果說我們有一個嚴重錯誤其中一段時間​​的服務器將被下載。紅寶石,數組時間的差距

拿這個陣列爲例:

[ 
    {:timestamp=>2011-09-26 19:00:00 UTC, :count=>318}, 
    {:timestamp=>2011-09-26 19:15:00 UTC, :count=>308}, 
    {:timestamp=>2011-09-26 19:30:00 UTC, :count=>222}, 
    {:timestamp=>2011-09-26 19:45:00 UTC, :count=>215}, 
    {:timestamp=>2011-09-26 20:00:00 UTC, :count=>166}, 
    {:timestamp=>2011-09-26 21:15:00 UTC, :count=>149}, 
    {:timestamp=>2011-09-26 21:30:00 UTC, :count=>145}, 
    {:timestamp=>2011-09-26 21:45:00 UTC, :count=>107}, 
    {:timestamp=>2011-09-26 22:00:00 UTC, :count=>137}, 
    {:timestamp=>2011-09-26 22:15:00 UTC, :count=>135}, 
    {:timestamp=>2011-09-26 22:30:00 UTC, :count=>191}, 
    {:timestamp=>2011-09-26 22:45:00 UTC, :count=>235} 
] 

你會發現,時間是缺少時間範圍:

{:timestamp=>2011-09-26 20:15:00 UTC}, 
{:timestamp=>2011-09-26 20:30:00 UTC}, 
{:timestamp=>2011-09-26 20:45:00 UTC}, 
{:timestamp=>2011-09-26 21:00:00 UTC} 

我怎樣才能把頂部爲輸入和演繹那些將是缺失的行?時間增量總是15分鐘,其實際上是一個真正的日期對象而不是像這樣的字符串。

我只是無法想象如何迭代這個。

任何幫助將不勝感激。

回答

3

我能想到的最簡單方法是爲了通過時間戳的數組,然後像做了以下內容:

missing_times = [] 
reports.each_with_index do |report, index| 
    if reports[index + 1] 
    if report.timestamp.advance(minutes: 15) < report[index + 1].timestamp 
     i = 0 
     while(report.timestamp.advance(minutes: 15*i) < report[index+1].timestamp) 
     missing_times << report.timestamp.advance(minutes: 15*i) 
     end 
    end 
    end 
end 

我以前寫類似的代碼,找出了一系列半小時的差距的預約

雖然看起來我的解決方案可能會在reports.first和reports.last之間以15分鐘的增量循環多次,但實際上它只會在所有可用的增量之間循環一次,報告之間的報告.first和reports.last

+0

我在執行此操作時遇到了一些麻煩,如果報告[:timestamp] .advance(分鐘:15)

0

只需從第一個時間戳開始,然後增加15分鐘,驗證該條目是否存在,並繼續前進,直到達到最後一個時間戳。

1

如果您以15分鐘的增量創建總時間範圍的數組,並且僅比較您的報告集並刪除所有匹配項,則不是在循環內執行多個循環,而是使用大型數據集更高效。

start_time = report.first 
span = ((report.last - start_time)/60/15).to_i # this gives the number of 15min blocks 
test_array = [] 
span.times do |i| 
    test_array << start_time + i*15.minutes 
end 
report.each do |r| 
    test_array.delete(r) # or in your case, r.timestamp 
end 

我認爲它的工作原理,但也想不出一個好辦法,使時間戳的參考表,所以我砍死了有我的方式。

+1

我的答案只在間隙大於15分鐘時循環,如果沒有間隙,我的解決方案只在數組上迭代一次。另外,我的數組不會循環所有可能的時間,只有那些填補空白。您的解決方案將始終有2個循環,一個負載時間跨度,另一個循環遍歷所有元素。當沒有差距時,您的解決方案將在所有元素上循環兩次。我最糟糕的情況將總是在所有可用增量上循環一次,等於你的'span.times'循環 –

+0

此外,test_array.delete迭代數組本身以找到要刪除的元素,請參閱代碼:http:// www。 ruby-doc.org/core/classes/Array.src/M000255.html,所以你的代碼是O(n^2),因爲每次你調用delete,你都可能遍歷整個數組 –

+0

你是對的 - 謝謝爲此解釋。 :) – joseph