将对象数组展平,排序和映射到散列数组(具有一些折叠值)

时间:2014-01-04 00:45:09

标签: ruby-on-rails ruby

情况:

我有一个对象数组。每个对象都有一个名称,ID和另一个属性。我想将此映射到具有name,数组id和其他属性(每个名称相同)的哈希数组。

所以我有类似的东西:

[{:name=>"Hello", :id=>1}, {:name=>"Hello", :id=>2}, {:name=>"Bye", :id=>3}]

我希望它看起来像

[{:name=>"Bye", :ids=>[3]}, {:name=>"Hello", :ids=>[1, 2]}]

我尝试过使用chunk,但我不能正确地弄清楚如何使用它而不是一大堆煮得不好的意大利面条。

现在我已经设法干净地排序(在开头),我可以很好地映射它,但我觉得进一步迭代它是不必要的浪费,我应该预先分组或组织它们。

没有分块,我的代码如下:

list_of_designers.sort!{ |x,y| I18n.transliterate(x.name).upcase <=> I18n.transliterate(y.name).upcase }

list_of_designers.map do |designer|
  {
    name: designer.name,
    designer_ids: [designer.id]
  }
end

然而,这让我留下兄弟姐妹(即设计师具有相同的名称,但ID不同)。我怎样才能彻底垮掉这些兄弟姐妹?

2 个答案:

答案 0 :(得分:2)

我会这样做:

a = [{:name=>"Hello", :id=>1}, {:name=>"Hello", :id=>2}, {:name=>"Bye", :id=>3}]
a.group_by{|h| h[:name] }.map{|k,v| {:name => k, :ids => v.map{|h| h[:id]}}}
# => [{:name=>"Hello", :ids=>[1, 2]}, {:name=>"Bye", :ids=>[3]}]

答案 1 :(得分:0)

试试这个:

original = [{:name=>"Hello", :id=>1}, {:name=>"Hello", :id=>2}, {:name=>"Bye", :id=>3}]
modified = original.map { |i| i[:name] }.uniq.map { |name| {name: name, ids: ary.find_all { |i| i[:name] == name }.map { |i| i[:id] } } }
# => [{:name=>"Hello", :ids=>[1, 2]}, {:name=>"Bye", :ids=>[3]}]