数组哈希ruby

好吧,所以这里的交易,我一直在search谷歌寻找解决办法,虽然有很多外面,他们似乎没有做我正在寻找的工作。

基本上我有一个这样的数组结构

["item 1", "item 2", "item 3", "item 4"] 

我想把它转换成一个哈希,所以它看起来像这样

 { "item 1" => "item 2", "item 3" => "item 4" } 

即“偶数”索引上的项是键,“奇数”索引上的项是数值。

任何想法如何做到这一点干净? 我想蛮力的方法是把所有的偶数索引都放到一个单独的数组中,然后在它们周围循环来添加值。

使用to_h

 a = ["item 1", "item 2", "item 3", "item 4"] h = a.to_h # => { "item 1" => "item 2", "item 3" => "item 4" } 

对于后人,下面是ruby <2.1.0版本的答案:


 a = ["item 1", "item 2", "item 3", "item 4"] h = Hash[*a] # => { "item 1" => "item 2", "item 3" => "item 4" } 

而已。 *被称为splat操作符。

每个@Mike Lewis的注意事项(在评论中):“要小心这个,Ruby会把splats扩展到堆栈上,如果你用大数据集来做这件事,那么期望把堆栈炸掉。

所以,对于大多数通用的用例来说,这个方法是好的,但是如果你想对大量的数据进行转换,可以使用一种不同的方法。 例如,@ŁukaszNiemier(也在评论中)为大数据集提供了这种方法:

 h = Hash[a.each_slice(2).to_a] 

Ruby 2.1.0在Array上引入了一个to_h方法,如果原始数组由键值对组成,就可以执行所需的操作: http : to_h 方法-i-to_h 。

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

或者如果你有一个[key, value]数组的数组,你可以这样做:

 [[1, 2], [3, 4]].inject({}) do |r, s| r.merge!({s[0] => s[1]}) end # => { 1 => 2, 3 => 4 } 

只需使用Hash.[]与数组中的值。 例如:

 arr = [1,2,3,4] Hash[*arr] #=> gives {1 => 2, 3 => 4} 

Enumerator包含Enumerable 。 从2.1Enumerable也有一个方法#to_h 。 这就是为什么我们可以这样写:

 a = ["item 1", "item 2", "item 3", "item 4"] a.each_slice(2).to_h # => {"item 1"=>"item 2", "item 3"=>"item 4"} 

因为#each_slice without block给了我们Enumerator ,并且按照上面的解释,我们可以在Enumerator对象上调用#to_h方法。

 a = ["item 1", "item 2", "item 3", "item 4"] Hash[ a.each_slice( 2 ).map { |e| e } ] 

或者,如果你讨厌Hash[ ... ]

 a.each_slice( 2 ).each_with_object Hash.new do |(k, v), h| h[k] = v end 

或者,如果你是一个破坏函数式编程的懒惰迷:

 h = a.lazy.each_slice( 2 ).tap { |a| break Hash.new { |h, k| h[k] = a.find { |e, _| e == k }[1] } } #=> {} h["item 1"] #=> "item 2" h["item 3"] #=> "item 4" 

你可以像这样尝试单个数组

 irb(main):019:0> a = ["item 1", "item 2", "item 3", "item 4"] => ["item 1", "item 2", "item 3", "item 4"] irb(main):020:0> Hash[*a] => {"item 1"=>"item 2", "item 3"=>"item 4"} 

数组的数组

 irb(main):022:0> a = [[1, 2], [3, 4]] => [[1, 2], [3, 4]] irb(main):023:0> Hash[*a.flatten] => {1=>2, 3=>4} 

这是我一直在寻找的时候这个search:

[{a: 1}, {b: 2}].reduce({}) { |h, v| h.merge v } => {:a=>1, :b=>2}