2016-02-11 58 views
0

我見過很多類似的問題,但這是一個非常特殊的情況。按鍵值對散列進行分組,同時將其他鍵值合併爲一個字符串

我有什麼作爲輸入:

entries = [ 
    {:action=>"X", :sequence=>1}, 
    {:action=>"Y", :sequence=>2}, 
    {:action=>"W", :sequence=>2}, 
    {:action=>"Z", :sequence=>3} 
] 

我想要什麼作爲輸出(加入由序列操作與 「和」,並與所有的行動 「」):

"X, Y and W, Z"

如何我已經做到了:

group = entries.group_by {|x| x.delete(:sequence)}.values 
=> [[{:action=>"X"}], [{:action=>"Y"}, {:action=>"W"}], [{:action=>"Z"}]] 

array = group.map { |el| el.map { |h| h[:action] } } 
=> [["X"], ["Y", "W"], ["Z"]] 

string = array.map { |a| a.join(' and ') }.join(', ') 
=> "X, Y and W, Z" 

它的工作原理,但它遠沒有乾淨。有沒有人有更好的解決方案?下面

+1

'Y'和'W'是如何區分的(都是序列2)?它看起來在你的輸出中分別與'X'和'Z'有關,但是可以在輸出中交換兩者嗎? –

+0

你說得對,我的錯。固定,其「X,Y和W,Z」。 –

回答

4

是最短的一個,我能想到的:

entries.group_by { |e| e.delete :sequence } 
     .values 
     .map { |e| e.map(&:values).join ' and ' } 
     .join ', ' 

另外一個[無損]:

entries.map(&:values) 
     .group_by(&:last) 
     .values 
     .map { |e| e.map(&:first).join ' and ' } 
     .join ', ' 

甚至:

entries.map(&:values) 
     .group_by(&:pop) 
     .values 
     .map { |e| e.join ' and ' } 
     .join ', ' 
+0

第二個比我的方式更好。好工作 –

+0

非常好。謝謝! –

1

,或者您可能玩each_with_object方法:

entries.each_with_object(Hash.new {[]}) do |e, m| 
    m[e[:sequence]] <<= e[:action] 
end.values 
    .map{|e| e.join(' and ')} 
    .join(", ") 
#=> "X, Y and W, Z" 
相關問題