在Ruby中展开一个哈希数组

20

我有一些简单的代码,看起来像这样:

fruit.each do |c|
  c.each do |key, value|
    puts value
  end
end

这样做是可行的,但感觉不够符合 Ruby 的风格。我的目标是将这个数组:

[{"fruit_id"=>"1"}, {"fruit_id"=>"2"}, {"fruit_id"=>"3"}]

将其转换为以下内容:

[ "1", "2", "3" ]

你的想法呢?

6个回答

41

如果是在Rails中或者你已经定义了to_proc,那么你可以用比@toholio的解决方案更简短的方式:

arr = [{"fruit_id"=>"1"}, {"fruit_id"=>"2"}, {"fruit_id"=>"3"}]
out = arr.map(&:values).flatten # => ["1", "2", "3"]

我希望我能够同时批准 - 这也很棒! - aronchick
嗯,实际上它们是同样的解决方案。 :) - toholio
8
针对1.9.3,有一个arr.flat_map(&:values)的表达式。 - jtzero

21

所以你希望将每个哈希转换为其值,然后与其他哈希的值连接起来吗?

in = [{"fruit_id"=>"1"}, {"fruit_id"=>"2"}, {"fruit_id"=>"3"}]
out = in.map{ |item| item.values }.flatten

out将会是["1","2","3"]


14

5

如果你使用map!,就不会在内存中创建另一个数组。

a.map! {|h| h.values}.flatten

这也可以写成:

a.map!(&:values).flatten!

看了一下评论,ruby 1.9.3中有一个方法叫做flat_maphttp://ruby-doc.org/core-1.9.3/Enumerable.html#method-i-flat_map),它可以在一次调用中完成映射和展平操作。

a.flat_map(&:values)

...或者至少不要使用局部变量。 - Taryn East

4
a.inject([]) { |mem,obj| mem += obj.values }

将元素注入空数组也被称为收集(或映射)。请参见此处的其他答案。 - glenn jackman
使用<<而不是+=来追加数组。这样会稍微快一些,因为您不会创建所有这些新的数组对象。 - glenn jackman
"<<和+ =不同。如果你想使用“<<”,你将不得不再次展平。无论如何,这只是小问题。" - Hemant Kumar

0

这不会改变太多,但你可以使用map

x.map do |fruit|
    fruit.each { |k,v| puts v }
end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接