【问题标题】:Convert array of arrays to hash with first array's element as a key to the hash将数组数组转换为散列,第一个数组的元素作为散列的键
【发布时间】:2015-07-01 09:36:03
【问题描述】:

我想转换这个数组

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

到这个哈希

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

怎么做?

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

【问题讨论】:

  • 请提供快速响应和帮助的代码。

标签: ruby-on-rails ruby ruby-2.2


【解决方案1】:

我会写:

key = a.shift
p a.map{|x| key.zip(x).to_h } => [{"a"=>"c", "b"=>"d"}, {"a"=>"e", "b"=>"f"}]

【讨论】:

    【解决方案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)
    

    【讨论】:

      【解决方案3】:
      ▶ 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] }
      

      【讨论】:

      • 我只是在尝试。谢谢您的回答。
      • 问题的一个转折点,假设如果我在一个数组中有 5 个元素而不是两个,并且我想忽略每个数组的第一个元素。?
      • 另外,您能否解释一下为什么您将 arr 数组从 1 变为 -1。为什么不 [1..2] ?
      • @ahmadhamza 此解决方案允许您在散列中包含任意数量的元素。要删除第一个元素,您需要将结果映射到 unshift 第一个元素。 [1..-1] 存在是因为原始数组可以是任意长度。
      【解决方案4】:
      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"}]
      

      改进:

      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"}]
      

      这种方式更灵活。

      【讨论】:

        【解决方案5】:
        x = [["a", "b"],["c", "d"],["e", "f"]]
        x[1..-1].map { |vs| {x[0][0] => vs[0], x[0][1] => vs[1]} }
        

        类似的东西。

        【讨论】:

        • 这适用于长度为 ≡ 3 的数组。在这种情况下,手动构建哈希会更容易。
        • @mudasobwa 你错了 - 不要混淆代码中的索引 [0] 和 [1]。代码是正确的。
        • @AndresEhrenpreis 哦,确实。当有 firstzip 访问器时,我的眼睛拒绝查看硬编码的数字索引。
        猜你喜欢
        • 2015-06-12
        • 2022-07-12
        • 1970-01-01
        • 2021-08-20
        • 2020-12-23
        • 2014-07-03
        • 2020-06-29
        • 2018-08-07
        • 2021-03-03
        相关资源
        最近更新 更多