在Ruby中,给定一个以下形式之一的数组......
[apple, 1, banana, 2] [[apple, 1], [banana, 2]]
...以...的形式将其转换为哈希的最佳方法是什么?
{apple => 1, banana => 2}
John Topley.. 144
简单地使用 Hash[*array_variable.flatten]
例如:
a1 = ['apple', 1, 'banana', 2] h1 = Hash[*a1.flatten(1)] puts "h1: #{h1.inspect}" a2 = [['apple', 1], ['banana', 2]] h2 = Hash[*a2.flatten(1)] puts "h2: #{h2.inspect}"
使用Array#flatten(1)
限制递归,因此Array
键和值按预期工作.
简单地使用 Hash[*array_variable.flatten]
例如:
a1 = ['apple', 1, 'banana', 2] h1 = Hash[*a1.flatten(1)] puts "h1: #{h1.inspect}" a2 = [['apple', 1], ['banana', 2]] h2 = Hash[*a2.flatten(1)] puts "h2: #{h2.inspect}"
使用Array#flatten(1)
限制递归,因此Array
键和值按预期工作.
注意:有关简洁有效的解决方案,请参阅下面的Marc-AndréLafortune的答案.
这个答案最初是作为使用flatten的方法的替代方法提供的,这是在撰写本文时最受欢迎的方法.我应该澄清一点,我不打算将这个例子作为最佳实践或有效方法.原始答案如下.
警告!使用flatten的解决方案不会保留数组键或值!
在@John Topley热门答案的基础上,让我们试试:
a3 = [ ['apple', 1], ['banana', 2], [['orange','seedless'], 3] ] h3 = Hash[*a3.flatten]
这会引发错误:
ArgumentError: odd number of arguments for Hash from (irb):10:in `[]' from (irb):10
构造函数期望一个偶数长度的数组(例如['k1','v1,'k2','v2']).更糟糕的是,一个扁平到均匀长度的不同数组会默默地给我们一个不正确值的哈希值.
如果要使用数组键或值,可以使用map:
h3 = Hash[a3.map {|key, value| [key, value]}] puts "h3: #{h3.inspect}"
这会保留Array键:
h3: {["orange", "seedless"]=>3, "apple"=>1, "banana"=>2}
最好的方法是使用Array#to_h
:
[ [:apple,1],[:banana,2] ].to_h #=> {apple: 1, banana: 2}
注意:这是在Ruby 2.1.0中引入的.对于较旧的Ruby,您可以使用我的to_h
gem to_h
,或者使用backports
:
[:apple, :banana].to_h { |fruit| [fruit, "I like #{fruit}s"] } # => {apple: "I like apples", banana: "I like bananas"}
这在Ruby 1.8.7及更高版本中可用.如果您仍在使用Ruby 1.8.6 require 'backports/2.6.0/enumerable/to_h'
,那么您也可以使用to_h
backport.
最后,虽然许多解决方案都使用Hash[]
,但这可能会产生数组本身的问题.
更新
Ruby 2.1.0今天发布.我附带Array#to_h
(发行说明和ruby-doc),它解决了转换Array
为a 的问题Hash
.
Ruby docs示例:
[[:foo, :bar], [1, 2]].to_h # => {:foo => :bar, 1 => 2}
编辑:看到我写作时发布的回复,哈希[a.flatten]似乎要走了.当我在思考响应时,一定是错过了文档中的那一点.我认为如果需要,我写的解决方案可以作为替代方案.
第二种形式更简单:
a = [[:apple, 1], [:banana, 2]] h = a.inject({}) { |r, i| r[i.first] = i.last; r }
a =数组,h =哈希,r =返回值哈希(我们累积的哈希),i =数组中的项目
我能想到做第一个表单的最好方法是这样的:
a = [:apple, 1, :banana, 2] h = {} a.each_slice(2) { |i| h[i.first] = i.last }
您还可以使用以下命令将2D数组转换为哈希:
1.9.3p362 :005 > a= [[1,2],[3,4]] => [[1, 2], [3, 4]] 1.9.3p362 :006 > h = Hash[a] => {1=>2, 3=>4}