这是我在Ruby中使用的一个对象。这是按日期排序的一堆事件,但是当对象中彼此相邻的两个或多个具有相同event_type时,我想将对象嵌套一层。
@events = [
{ :id => 1, :event_type => "B", :created_at => "2013-09-30 14:44:24 UTC"},
{ :id => 2, :event_type => "A", :created_at => "2013-09-29 14:44:24 UTC"},
{ :id => 3, :event_type => "A", :created_at => "2013-09-28 14:44:24 UTC"},
{ :id => 4, :event_type => "C", :created_at => "2013-09-27 14:44:24 UTC"},
{ :id => 5, :event_type => "C", :created_at => "2013-09-26 14:44:24 UTC"},
{ :id => 6, :event_type => "A", :created_at => "2013-09-25 14:44:24 UTC"}
]
我想把它变成这个:
@events = [
{ :id => 1, :event_type => "B", :created_at => "2013-09-30 14:44:24 UTC"},
{ :grouped_events => [
{ :id => 2, :event_type => "A", :created_at => "2013-09-29 14:44:24 UTC"},
{ :id => 3, :event_type => "A", :created_at => "2013-09-28 14:44:24 UTC"}
]
},
{ :grouped_events => [
{ :id => 4, :event_type => "C", :created_at => "2013-09-27 14:44:24 UTC"},
{ :id => 5, :event_type => "C", :created_at => "2013-09-26 14:44:24 UTC"}
]
},
{ :id => 6, :event_type => "A", :created_at => "2013-09-25 14:44:24 UTC"}
]
我需要整个对象来保持嵌套对象按日期排序,但如果有两个或更多事件聚集在一起,我希望它们变成一个数组,如示例输出所示。 这似乎是一个简单的问题,但我似乎无法弄明白。
答案 0 :(得分:2)
保持订单使用Enumerable
的{{3}}方法:
@events = [
{ :id => 1, :event_type => "B", :created_at => "2013-09-30 14:44:24 UTC"},
{ :id => 1, :event_type => "A", :created_at => "2013-09-29 14:44:24 UTC"},
{ :id => 1, :event_type => "A", :created_at => "2013-09-28 14:44:24 UTC"},
{ :id => 1, :event_type => "C", :created_at => "2013-09-27 14:44:24 UTC"},
{ :id => 1, :event_type => "C", :created_at => "2013-09-26 14:44:24 UTC"},
{ :id => 1, :event_type => "A", :created_at => "2013-09-25 14:44:24 UTC"}
]
p @events.chunk{|el| el[:event_type]}.map{|gr| gr[1]}
输出:
#=> [[{:id=>1, :event_type=>"B", :created_at=>"2013-09-30 14:44:24 UTC"}],
#=> [{:id=>1, :event_type=>"A", :created_at=>"2013-09-29 14:44:24 UTC"},
#=> {:id=>1, :event_type=>"A", :created_at=>"2013-09-28 14:44:24 UTC"}],
#=> [{:id=>1, :event_type=>"C", :created_at=>"2013-09-27 14:44:24 UTC"},
#=> {:id=>1, :event_type=>"C", :created_at=>"2013-09-26 14:44:24 UTC"}],
#=> [{:id=>1, :event_type=>"A", :created_at=>"2013-09-25 14:44:24 UTC"}]]
或者,如果您只想在有2个或更多元素的情况下尝试使用数组:
p @events
.chunk{|el| el[:event_type]}
.flat_map{|gr| gr[1].length == 1 ? gr[1] : [gr[1]]}
输出
#=> [
#=> {:id=>1, :event_type=>"B", :created_at=>"2013-09-30 14:44:24 UTC"},
#=> [{:id=>1, :event_type=>"A", :created_at=>"2013-09-29 14:44:24 UTC"},
#=> {:id=>1, :event_type=>"A", :created_at=>"2013-09-28 14:44:24 UTC"}],
#=> [{:id=>1, :event_type=>"C", :created_at=>"2013-09-27 14:44:24 UTC"},
#=> {:id=>1, :event_type=>"C", :created_at=>"2013-09-26 14:44:24 UTC"}],
#=> {:id=>1, :event_type=>"A", :created_at=>"2013-09-25 14:44:24 UTC"}
#=> ]
<强>更新强>
您可以动态更改输出格式:)
对于您的上一个变体,请尝试以下方法:
p @events
.chunk{|el| el[:event_type]}
.flat_map{|gr|
gr[1].length == 1 ? gr[1] : {:grouped_events => gr[1]}
}
答案 1 :(得分:0)
怎么样?
p @events.group_by{|item| item[:event_type]}.values #=>
# [[{:id=>1, :event_type=>"B", :created_at=>"2013-09-30 14:44:24 UTC"}],
# [{:id=>1, :event_type=>"A", :created_at=>"2013-09-29 14:44:24 UTC"},
# {:id=>1, :event_type=>"A", :created_at=>"2013-09-28 14:44:24 UTC"},
# {:id=>1, :event_type=>"A", :created_at=>"2013-09-25 14:44:24 UTC"}],
# [{:id=>1, :event_type=>"C", :created_at=>"2013-09-27 14:44:24 UTC"},
# {:id=>1, :event_type=>"C", :created_at=>"2013-09-26 14:44:24 UTC"}]]