Ruby将两个阵列合并为一个

lou*_*221 23 ruby arrays hash iterator ruby-on-rails

这是我的情况.我有2个阵列

@names = ["Tom", "Harry", "John"]

@emails = ["tom@gmail.com", "h@gmail.com", "j@gmail.com"]
Run Code Online (Sandbox Code Playgroud)

我想将这两个组合成一些调用的Array/Hash,@list这样我就可以在我的视图中迭代这样的东西:

<% @list.each do |item| %>
<%= item.name %><br>
<%= item.email %><br>
<% end %>
Run Code Online (Sandbox Code Playgroud)

我无法理解如何实现这一目标.有什么想法吗?

Phr*_*ogz 50

@names  = ["Tom", "Harry", "John"]
@emails = ["tom@gmail.com", "h@gmail.com", "j@gmail.com"]

@list = @names.zip( @emails )
#=> [["Tom", "tom@gmail.com"], ["Harry", "h@gmail.com"], ["John", "j@gmail.com"]]

@list.each do |name,email|
  # When a block is passed an array you can automatically "destructure"
  # the array parts into named variables. Yay for Ruby!
  p "#{name} <#{email}>"
end
#=> "Tom <tom@gmail.com>"
#=> "Harry <h@gmail.com>"
#=> "John <j@gmail.com>"

@urls = ["yahoo.com", "ebay.com", "google.com"]

# Zipping multiple arrays together
@names.zip( @emails, @urls ).each do |name,email,url|
  p "#{name} <#{email}> :: #{url}"
end
#=> "Tom <tom@gmail.com> :: yahoo.com"
#=> "Harry <h@gmail.com> :: ebay.com"
#=> "John <j@gmail.com> :: google.com"
Run Code Online (Sandbox Code Playgroud)

  • 啊哈!所以*这*是'zip`的用途!它不知何故从未真正进入我的标准工具箱.尼斯.+1 (4认同)

Dig*_*oss 16

只是为了与众不同:

[@names, @emails, @urls].transpose.each do |name, email, url|
  # . . .
end
Run Code Online (Sandbox Code Playgroud)

这类似于Array#zip所做的,除了在这种情况下不会有任何短行的nil填充; 如果缺少某些东西,将引发异常.

  • 转置的提示很棒.感谢发布此内容 (5认同)

Sea*_*ill 7

Hash[*names.zip(emails).flatten]
Run Code Online (Sandbox Code Playgroud)

这将为您提供名称=>电子邮件的哈希.

  • 在Ruby 1.9下你可以简单地做:`哈希[names.zip(电子邮件)]` (7认同)
  • 适用于这种情况,但未来的读者要注意:这不是一个通用的解决方案,因为如果 `names` 或 `emails` 是包含数组的数组,`flatten` 将递归运行。 (2认同)
  • 如果需要,flatten(1)将阻止递归. (2认同)