我见过很多类似的问题,但这是一个非常具体的案例。
我有什么输入:
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"
它有效,但它远非干净。有没有人有更好的解决方案?
答案 0 :(得分: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 ', '
答案 1 :(得分: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"