2

假设我有这两个数组:

a = [1, 2, 3, 4, 5]
b = [6, 7, 8, 9, 10]

我想要得到的是一个哈希,如下所示:

c = { 1 => [1, 6], 2 => [2, 7], 3 => [3, 8], 4 => [4, 9], 5 => [5, 10] }

到目前为止,我遇到的唯一方法如下:

# Initialize the resulting Hash and fill in the keys.
c = {}
(a.length).times { |i| c[i + 1] = [] }

# Fill values
c.each_with_index do |(key), idx|
  c[key] = [a[idx], b[idx]]
end

Ruby 有更好或更漂亮的方法来做到这一点吗?

提前致谢。

4

4 回答 4

10

功能方法:

Hash[a.zip(b).map.with_index(1) { |pair, idx| [idx, pair] }]
#=> {1=>[1, 6], 2=>[2, 7], 3=>[3, 8], 4=>[4, 9], 5=>[5, 10]}

只是为了好玩,如果你想构建自己的抽象:前面的代码片段比它应该的更冗长with_index,首先它只适用于枚举器(而不是枚举器),其次它将值作为第二个元素(它会是第一个更有用,这是大多数其他语言所做的)。我们能做什么?添加我们自己的Enumerable#indexed方法,以相反的方式工作。在这一点上,我们将不得不添加 add Enumerable#to_h,所以最终我们可以编写这个纯 OOP、从左到右的声明性代码:

a.zip(b).indexed(1).to_h
于 2013-06-06T08:30:30.043 回答
8
c = Hash[(1..a.size).zip(a.zip(b))]

这利用了Hash 的键值对初始化器

于 2013-06-06T08:38:21.923 回答
0

你已经得到了很多很好的答案。为了多样性,我将再添加两个。

Hash[(0...a.size).map{ |i| [i+1, [a[i], b[i]]] } ]

或者

(0...a.size).each_with_object({}) { |i, h| h[i+1] = [a[i], b[i]] }

我认为这些版本更容易阅读和理解。:) 然而,这是一个品味问题。

更新:

我不能停下来。:-) 这里还有一个:

a.zip(b).each_with_object({}) { |p, h| h[h.size+1] = p }
于 2013-06-06T18:18:19.397 回答
0

Ruby 有更好或更漂亮的方法吗?

当然,确实如此!

a = [1, 2, 3, 4, 5]
b = [6, 7, 8, 9, 10]

c = a.zip(b).each.with_index.with_object({}) do |(arr, idx), memo|
  memo[idx + 1] = arr
end

c # => {1=>[1, 6], 2=>[2, 7], 3=>[3, 8], 4=>[4, 9], 5=>[5, 10]}
于 2013-06-06T08:30:08.133 回答