在Ruby中将数组转换为哈希表,同时保留数组索引值

14

我有一个包含 X 个值的数组。下面的数组只有4个,但我需要代码动态化,不仅依赖于只有四个数组对象。

array = ["Adult", "Family", "Single", "Child"]

我想将 array 转换为以下样式的哈希表:

hash = {0 => 'Adult', 1 => 'Family', 2 => 'Single', 3 => 'Child'}

哈希表应该有和数组对象一样多的键/值对,值应该从0开始,每个对象递增1。

4个回答

17
使用Enumerable#each_with_index
Hash[array.each_with_index.map { |value, index| [index, value] }]
# => {0=>"Adult", 1=>"Family", 2=>"Single", 3=>"Child"}

正如@hirolau所评论的那样,each_with_index.map也可以写成map.with_index

Hash[array.map.with_index { |value, index| [index, value] }]
# => {0=>"Adult", 1=>"Family", 2=>"Single", 3=>"Child"}

更新

使用Hash#invert的替代方法:

Hash[array.map.with_index{|*x|x}].invert
# => {0=>"Adult", 1=>"Family", 2=>"Single", 3=>"Child"}
Hash[[*array.map.with_index]].invert
# => {0=>"Adult", 1=>"Family", 2=>"Single", 3=>"Child"}

太棒了,就这样吧。谢谢你的提示。 - Luigi
3
each_with_index.map也可以写成map.with_index,只是稍微更好一些。 - hirolau
2
Hash[array.map.with_index{|*x|x}].invert - hirolau
@hirolau,感谢您的评论。我已经加入了您的建议。 - falsetru
@hirolao,谢谢你。我看到还有with_object。在Enumerable方法之后放置它们更好。 - Cary Swoveland

7

另一个例子:

Hash[array.each_index.zip(array)]
#=> {0=>"Adult", 1=>"Family", 2=>"Single", 3=>"Child"}

较新的Ruby版本将允许:
array.each_with_index.to_h.invert
#=> {0=>"Adult", 1=>"Family", 2=>"Single", 3=>"Child"}

1
  Hash[*(0..array.size-1).to_a.zip(array)]
    => {0=>"Adult", 1=>"Family", 2=>"Single", 3=>"Child"} 

4
好的!我们甚至可以更简洁 - Hash[(0...array.size).zip(array)] 可以翻译为:很好!我们可以更简洁 - Hash[(0...array.size).zip(array)] - Alex.Bullard
非常好,@Alex。感谢你的提示。我倾向于避免在范围中使用三个点(除了高尔夫球)——太容易错过了。 - Cary Swoveland

0

试试这个

array.each_with_index.inject({}){ |hash, (val, i)| hash[i]=val; hash }
=> {0=>"Adult", 1=>"Family", 2=>"Single", 3=>"Child"} 

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