你說你想分組,他們是多麼接近彼此。你需要的是一羣以#created_at值的子集,這樣的:
require "rubygems"
require "active_support/core_ext/array"
require "ostruct"
require "pp"
o1 = OpenStruct.new(:created_at => Time.local(2010, 11, 24, 20, 1, 0, 0))
o2 = OpenStruct.new(:created_at => Time.local(2010, 11, 24, 20, 2, 0, 0))
o3 = OpenStruct.new(:created_at => Time.local(2010, 11, 24, 20, 6, 0, 0))
o4 = OpenStruct.new(:created_at => Time.local(2010, 11, 24, 20, 13, 0, 0))
a = [o1, o2, o3, o4]
grouped = a.group_by do |obj|
time = obj.created_at
Time.local(time.year, time.month, time.day, time.hour, (time.min/5).floor, 0)
end
pp grouped.map {|val, arr| [val, arr.map {|obj| obj.created_at.to_s }] }
將返回:
$ ruby a.rb
[[Wed Nov 24 20:02:00 -0500 2010, ["Wed Nov 24 20:13:00 -0500 2010"]],
[Wed Nov 24 20:00:00 -0500 2010,
["Wed Nov 24 20:01:00 -0500 2010", "Wed Nov 24 20:02:00 -0500 2010"]],
[Wed Nov 24 20:01:00 -0500 2010, ["Wed Nov 24 20:06:00 -0500 2010"]]]
,每個密閉數組的第一個值在5組的關鍵(分分鐘),並且這些值是實際的ActiveRecord對象。爲了便於閱讀,我已經映射到了Time的String版本,但它是一樣的想法。
還要記住,#group_by生成的數組與原始數組的排序方式相同,因此您的排序約束將得以保留 - 您不需要使用數組。
你NoMethodError可能的原因是因爲第一次GROUP_BY塊被調用時,索引是0,你從中減去1,最後試圖得到一個[-1] .created_at這當然失敗了。試圖想出一個更好的方式來做到這一點... – DanneManne 2010-11-24 14:07:23
哦,當然。但我仍然不喜歡再次從哈希中獲取相同節點以找出索引等的想法。 – Charles 2010-11-24 14:12:18
這些項目是通過ActiveRecord還是其中一個ORM來自數據庫的?如果是這樣,讓DBM做「計算」可能是更好的攻擊計劃。在內存中進行分組可能會很昂貴,特別是如果您有大量記錄。如果是這種情況,您可能需要爲ActiveRecord或ORM的問題添加標籤。 – 2010-11-24 18:46:20