2

我想转换这个数组

[['a', 'b'],['c', 'd'],['e', 'f']] 

到这个哈希

{
  "a" : "c",
  "b" : "d"
},
{
  "a" : "e",
  "b" : "f"
}

怎么做?

我尝试使用group_by和普通的迭代器,但到目前为止没有运气。有任何想法吗?

4

5 回答 5

7
▶ arr = [[:a, :b],[:c, :d],[:e, :f],[:g, :h]]
▶ key, values = arr.first, arr[1..-1]
▶ values.map { |v| key.zip v }.map &:to_h
#⇒ [
#  [0] {
#    :a => :c,
#    :b => :d
#  },
#  [1] {
#    :a => :e,
#    :b => :f
#  },
#  [2] {
#    :a => :g,
#    :b => :h
#  }
# ]

请注意,与目前此处介绍的其他解决方案不同,此解决方案会将第一个元素作为键映射到任意长度的尾部。

UPD对于遗留红宝石,没有Array#to_h

values.map { |v| key.zip v }.map { |e| Hash[e] }
于 2015-04-23T09:43:40.663 回答
2

我会使用Array#product

arr = [[:a, :b], [:c, :d], [:e, :f]]

arr.first.product(arr[1..-1]).map(&:to_h)
  #=> [{:a=>:c, :b=>:d}, {:a=>:e, :b=>:f}]

如果arr可以修改,我们可以这样写:

arr.shift.product(arr).map(&:to_h)
于 2015-04-23T12:07:58.503 回答
1
x = [["a", "b"],["c", "d"],["e", "f"]]
x[1..-1].map { |vs| {x[0][0] => vs[0], x[0][1] => vs[1]} }

像这样的东西。

于 2015-04-23T09:43:25.540 回答
1
a= [['a', 'b'],['c', 'd'],['e', 'f']]

a[1..-1].inject([]) { |sum, s| sum << {a[0][0] => s[0], a[0][1] => s[1]} }

=> [{"a"=>"c", "b"=>"d"}, {"a"=>"e", "b"=>"f"}]

改进:</p>

a= [['a', 'b', 'c'],['d', 'e', 'f'],['g', 'h', 'k']]
a[1..-1].inject([]) do |sum, s|
    hash = {}
    a[0].each_with_index { |it, i| hash.merge!({it => s[i]}) }
    sum << hash
end
=> [{"a"=>"d", "b"=>"e", "c"=>"f"}, {"a"=>"g", "b"=>"h", "c"=>"k"}]

这种方式更加灵活。

于 2015-04-23T09:48:13.130 回答
1

我会写:

key = a.shift
p a.map{|x| key.zip(x).to_h } => [{"a"=>"c", "b"=>"d"}, {"a"=>"e", "b"=>"f"}]
于 2015-04-23T14:13:34.140 回答