1

这是我在 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"}
]

我需要整个对象来保持嵌套对象按日期排序,但如果有 2 个或更多事件聚集在一起,我希望它们变成一个数组,如示例输出所示。这似乎是一个简单的问题,但我似乎无法弄清楚。

4

2 回答 2

2

为了保持订单使用方法Enumerable

@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]}
  }
于 2013-10-01T17:15:33.650 回答
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"}]]
于 2013-10-01T17:02:36.783 回答