当前位置:  开发笔记 > 后端 > 正文

在Ruby中将数组转换为散列的最佳方法是什么?

如何解决《在Ruby中将数组转换为散列的最佳方法是什么?》经验,为你挑选了6个好方法。

在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键和值按预期工作.



1> John Topley..:

简单地使用 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键和值按预期工作.


警告:如果需要数组键或值,使用展平的答案会导致问题.
FWIW,如果你真的想要(更多)一个尺寸适合所有版本,你也可以使用`Hash [*ary.flatten(1)]`,这将保留数组键和值.它是递归的"flatten",正在摧毁那些,这很容易避免.
最好不要尝试为此做一个全面的解决方案.如果你的键和值在[[key1,value1],[key2,value2]]中配对,那么只需将它传递给Hash []而不加肥.哈希[a2] ==哈希[*a2.flatten].如果数组已经被展平,如[key1,value1,key2,value2]那么只需在var前加上*,Hash [*a1]
哦,口才!这就是我喜欢Ruby的原因

2> Stew..:

注意:有关简洁有效的解决方案,请参阅下面的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}


这与Hash [a3]相同,因为a3 == a3.map {| k,v | [k,v]}是真的,它实际上相当于a3.dup.
这个答案效率不高.它也已经过时了.看我的回答.
而不是使用地图,为什么不指定展平的深度?例如:`h3 = Hash [*a3.flatten(1)]`而不是`h3 = Hash [*a3.flatten]`会抛出错误.

3> Marc-André L..:

最好的方法是使用Array#to_h:

[ [:apple,1],[:banana,2] ].to_h  #=> {apple: 1, banana: 2}

注意:这是在Ruby 2.1.0中引入的.对于较旧的Ruby,您可以使用我的to_hgem 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_hbackport.

最后,虽然许多解决方案都使用Hash[],但这可能会产生数组本身的问题.


感谢新.to_h方法的简单性!
我认为这应该是接受的答案
我比上面的答案更喜欢`to_h`方法,因为它表达了在***操作数组后转换***的意图.

4> 小智..:

更新

Ruby 2.1.0今天发布.我附带Array#to_h(发行说明和ruby-doc),它解决了转换Array为a 的问题Hash.

Ruby docs示例:

[[:foo, :bar], [1, 2]].to_h    # => {:foo => :bar, 1 => 2}



5> Daemin..:

编辑:看到我写作时发布的回复,哈希[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 }


'a.inject({})`one-liner的+1,允许更灵活的值赋值.

6> 小智..:

您还可以使用以下命令将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} 

推荐阅读
爱唱歌的郭少文_
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有