我有下面的数组,我想将它转换为一个散列,其中键如年龄,值如人名。此外,我想确保同龄的人属于同一把钥匙。
ages = [ ['alpha', 20], ['beta',21], ['charlie',23], ['delta', 20] , ['gamma', 23]]
我如何将上面的内容转换成下面这样的散列?
例如{20 => ['alpha','delta'] }
等
我已经尝试了以下代码,但我被卡住了:
hash = Hash[ages.collect {|item| [item[1], item[0]]} ]
pp散列
谢谢。
可能的解决方案之一是使用:
hash = ages.each_with_object(Hash.new {|h,k| h[k] = [] }) do |obj, res|
res[obj.last] << obj.first
end
=> {20=>["alpha", "delta"], 21=>["beta"], 23=>["charlie", "gamma"]}
Hash#default_proc
Enumerable#each_with_object
还有另一种方法:使用可枚举#group_by 哈希#transform_values
ages.
group_by(&:second).
transform_values { |entries| entries.map(&:first) }
# => {20=>["alpha", "delta"], 21=>["beta"], 23=>["charlie", "gamma"]}
您可以先创建哈希,然后在年龄之间循环,将年龄相似的成员收集到数组中。
hash = Hash.new{|h,k|h[k]=Array.new()}
ages.each do |age|
hash[age.last]<<age.first
end
p hash #{20=>["alpha", "delta"], 21=>["beta"], 23=>["charlie", "gamma"]}
ages.each_with_object({}) do |(str,x),h|
(h[x] ||= []) << str
end
#=> {20=>["alpha", "delta"], 21=>["beta"], 23=>["charlie", "gamma"]}
h[x] ||= []
扩展到
h[x] = h[x] || []
如果h
没有密钥x
,则变为
h[x] = nil || []
使得h[x]
被设置为等于空数组,之后执行h[x] << str
。
将块变量表示为|(str,x),h|
利用Ruby的数组分解:
enum = ages.each_with_object({})
#=> #<Enumerator: [["alpha", 20], ["beta", 21], ["charlie", 23],
# ["delta", 20], ["gamma", 23]]:each_with_object({})>
(str,x),h = enum.next
#=> [["alpha", 20], {}]
str
#=> "alpha"
x #=> 20
h #=> {}
(h[x] ||= []) << str
#=> ["alpha"]
(str,x),h = enum.next
#=> [["beta", 21], {20=>["alpha"]}]
等等