Ruby数组转哈希:将每个元素作为键,并从中派生值

29
我有一个字符串数组,想要将其转换为哈希表。数组的每个元素将作为键,我想让值由该键计算而来。是否有一种用Ruby实现的方法?
例如: ['a','b'] 转换为 {'a'=> 'A','b'=> 'B'}

字符串是唯一的吗?如果不是,您想要异常吗? - Art Shayderov
是的,它们将是唯一的。如果不是,我会在此之前执行 uniq 命令。 - lulalala
9个回答

56

你可以:

a = ['a', 'b']
Hash[a.map {|v| [v,v.upcase]}]

4
这确实可行......但我认为这不是高效的方法......在这种情况下,您需要两次迭代。当然,在长度为2的数组中这不是问题,但仍值得注意。 - brad

22
%w{a b c}.reduce({}){|a,v| a[v] = v.upcase; a}

我喜欢你的解决方案!非常流畅! - Jens Tinfors

8

Ruby的each_with_object方法是一个很好的完成你想要的事情的方式。

['a', 'b'].each_with_object({}) { |k, h| h[k] = k.upcase }

6

从Rails 6.x开始,您可以使用Enumerable#index_with

irb(main):002:0> ['a', 'b'].index_with {|s| s.upcase}
=> {"a"=>"A", "b"=>"B"}

6
这里有另外一种方法:
a.zip(a.map(&:upcase)).to_h

#=>{"a"=>"A", "b"=>"B"}

5
无论你如何看待它,你都需要迭代初始数组。这里是另一种方法:
a = ['a', 'b', 'c']
h = Hash[a.collect {|v| [v, v.upcase]}]
#=> {"a"=>"A", "b"=>"B", "c"=>"C"}

4
这里有一个天真而简单的解决方案,将当前字符转换为用作键的符号。只是为了好玩,它将值大写。 :)
h = Hash.new
['a', 'b'].each {|a| h[a.to_sym] = a.upcase}
puts h

# => {:a=>"A", :b=>"B"}

3

.to_h传递一个块

[ 'a', 'b' ].to_h{ |element| [ element, element.upcase ] }
#=> {"a"=>"A", "b"=>"B"}

感谢 @SMAG 的重构建议!


1
你可以直接将块传递给 to_h 方法。示例代码如下: [ 'a', 'b' ].to_h { |element| [ element, element.upcase ] } - SMAG
1
你可以直接将块传递给 to_h 方法。 - SMAG
@SMAG 哇,太棒了。他们最近添加了这个功能吗?或者你知道是哪个版本的Ruby添加了这个功能吗? - Joshua Pinter
看起来是在2.3和2.7之间的某个时间添加的,根据我提供的链接,但不确定如何更具体地获取信息。 - SMAG
看起来是在2.3和2.7之间的某个时间点添加的,根据我提供的链接,但不确定如何进一步具体确定。 - SMAG
@SMAG 这已经足够好了。看起来它已经存在了相当长的时间,人们可以参考您的评论以获得最低版本要求的大致想法。感谢您的研究。 - Joshua Pinter

1

不确定这是否是真正的 Ruby 方法,但应该足够接近:

hash = {}
['a', 'b'].each do |x|
  hash[x] = x.upcase
end

p hash  # prints {"a"=>"A", "b"=>"B"}

作为一个函数,我们会有这个:
def theFunk(array)
  hash = {}
  array.each do |x|
    hash[x] = x.upcase
  end
  hash
end


p theFunk ['a', 'b', 'c']  # prints {"a"=>"A", "b"=>"B", "c"=>"C"}

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