簡體   English   中英

如何按多個字段將Ruby可枚舉/數組分組?

[英]How to group Ruby enumerable/array by more than one field?

我有一個數據結構事件:

Event = Struct.new(:action, :date, :id)

data= []
data << Event.new('action1', '1/8/2014', 1)
data << Event.new('action1', '1/8/2014', 2)
data << Event.new('action1', '1/8/2014', 3)
data << Event.new('action1', '8/8/2014', 4)
data << Event.new('action2', '1/8/2014', 5)
data << Event.new('action2', '2/8/2014', 6)
data << Event.new('action2', '2/8/2014', 7)

我想根據操作日期對數據進行分組,以獲得最終結果:

{ 
 "action1" => {'1/8/2014' => 3, '8/8/2014' => 1 },
 "action2" => {'1/8/2014' => 1, '2/8/2014' => 2 }
}

最終結果顯示,動作1在“ 1/8/2014”重復了3次,在“ 8/8/2014”重復了1次。 動作2在“ 1/8/2014”一次,在“ 2/8/2014”兩次。

我嘗試先使用#group_by{|x| x.action}通過操作將結果#group_by{|x| x.action} #group_by{|x| x.action}然后試圖用注射,但我的解決方案是什么,但簡單。

Hash.new{|h, k| h[k] = Hash.new{|h, k| h[k] = 0}}
.tap{|h| data.each{|e| h[e.action][e.date] += 1}}

結果h為:

{
  "action1" => {"1/8/2014" => 3, "8/8/2014" => 1},
  "action2" => {"1/8/2014" => 1, "2/8/2014" => 2}
}

要么,

data.each_with_object(Hash.new{|h, k| h[k] = Hash.new{|h, k| h[k] = 0}}) do
  |e, h| h[e.action][e.date] += 1
end

@sawa提供了一個不錯的解決方案,但這里還有兩個。 我更喜歡第一個,第二個則不太喜歡,盡管我認為可以簡化一些。

#1

這利用了采用一個塊的Hash#update (又名merge )的形式。 該塊僅對鍵值對起作用,鍵值對由正在構建的哈希和正在合並的哈希包含鍵。 回想一下,當在塊中未使用塊變量時,可以用下划線(或下划線后跟描述符,例如_key_key塊變量。 (使用下划線僅引起注意。)

data.each_with_object({}) do |d,h|
  h.update({ d.action=>{ d.date=>1 } }) do |_,ohash,_|
    ohash[d.date] = (ohash[d.date] || 0) + 1
    ohash
  end
end
  #=> {"action1"=>{"1/8/2014"=>3, "8/8/2014"=>1}, 
  #    "action2"=>{"1/8/2014"=>1, "2/8/2014"=>2}}

#2

第二種方法在兩個級別的每個級別上使用Enumerable#group_by ,以按操作首先分組,然后為每個操作按日期分組。

data.map { |d| [d.action, d.date] }
    .group_by(&:first)
    .tap { |h| h.keys.each { |k|
                 h[k]=h[k].group_by { |_,d| d }
                          .tap { |g| g.keys.each {|kk| g[kk]=g[kk].size} } } }
  #=> {"action1"=>{"1/8/2014"=>3, "8/8/2014"=>1}, 
  #    "action2"=>{"1/8/2014"=>1, "2/8/2014"=>2}}

如果有興趣,我將很樂意為您介紹這兩種方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM