【问题标题】:Converting array of key value pairs to hash in Ruby在Ruby中将键值对数组转换为哈希
【发布时间】:2016-02-05 19:04:24
【问题描述】:

我在一个数组中有一些键值对字符串:

array = [ "Name = abc", "Id = 123", "Interest = Rock Climbing" ]

我需要将其转换为哈希:

hash = { "Name" => "abc", "Id" => "123", "Interest" => "Rock Climbing" }

我一定是做错了什么,因为我的.shift.split 得到了奇怪的映射,导致{"Name=abc"=>"Id=123"}

【问题讨论】:

    标签: arrays ruby hash key-value


    【解决方案1】:

    您需要做的就是将数组的每个部分拆分为一个键和一个值(生成一个由两个元素数组组成的数组),然后将结果传递给方便的Hash[] 方法:

    arr = [ "Name = abc", "Id = 123", "Interest = Rock Climbing" ]
    
    keys_values = arr.map {|item| item.split /\s*=\s*/ }
    # => [ [ "Name", "abc" ],
    #      [ "Id", "123" ],
    #      [ "Interest", "Rock Climbing" ] ]
    
    hsh = Hash[keys_values]
    # => { "Name" => "abc",
    #      "Id" => "123",
    #      "Interest" => "Rock Climbing" }
    

    【讨论】:

    • 我试过你上面的代码,它给了我下面的错误wrong array length at 20 (expected 2, was 3) 谁能帮我解决这个问题。此外,相同的代码仅在极少数情况下对我不起作用,但是我看不出工作和不工作情况的值差异。
    • @VinitSharma Hash[] 方法需要成对的数据,即每个包含两个元素的数组数组,例如 [[key1, val1], [key2, val2], ...]。错误告诉您其中一个数组包含三个元素而不是两个。
    • 是的,你是对的,我的源字符串创建不正确,因为一个空格包含两个以上的元素。删除了空白区域及其现在的工作。感谢您的帮助!
    【解决方案2】:

    你可以这样做(使用Enumerable#each_with_object):

    array.each_with_object({}) do |a, hash|
        key,value = a.split(/\s*=\s*/) # splitting the array items into key and value
        hash[key] = value    # storing key => value pairs in the hash
    end
    # => {"Name"=>"abc", "Id"=>"123", "Interest"=>"Rock Climbing"}
    

    如果你觉得each_with_object有点难以理解,你可以用一种幼稚的方式来做(只需在result_hash中积累keyvalues):

    result_hash = {}
    array.each do |a|
        key,value = a.split(/\s*=\s*/) # splitting the array items into key and value
        result_hash[key] = value # storing key => value pairs in the result_hash
    end
    result_hash
    # => {"Name"=>"abc", "Id"=>"123", "Interest"=>"Rock Climbing"}
    

    【讨论】:

      【解决方案3】:

      试试这个

      array.map {|s| s.split('=')}.to_h
      
      => {"Name "=>" abc", "Id "=>" 123", "Interest "=>" Rock Climbing"} 
      

      【讨论】:

        【解决方案4】:
        array.each_with_object({}) { |s,h| h.update([s.split(/\s*=\s*/)].to_h) }
          #=> {"Name"=>"abc", "Id"=>"123", "Interest"=>"Rock Climbing"} 
        

        对于 2.0 之前的 Ruby 版本(当引入 Array#to_h 时)将 [s.split(/\s*=\s*/)].h 替换为 Hash[[s.split(/\s*=\s*/)]]。 步骤:

        enum = array.each_with_object({})
          #=> #<Enumerator: ["Name = abc", "Id = 123",
          #     "Interest = Rock Climbing"]:each_with_object({})>
        

        我们可以通过将这个枚举器转换为数组来查看它的元素:

        enum.to_a
          #=> [["Name = abc", {}], ["Id = 123", {}], ["Interest = Rock Climbing", {}]] 
        

        enum的第一个元素被传递给block,block变量被赋值:

        s,h = enum.next
          #=> ["Name = abc", {}] 
        s #=> "Name = abc" 
        h #=> {} 
        

        并进行块计算:

        h.update([s.split(/\s*=\s*/)].to_h)
          #=> h.update([["Name", "abc"]].to_h) 
          #   {}.update({"Name"=>"abc"})
          #   {"Name"=>"abc"}
        

        这是h的更新值。

        enum 传递给块的下一个元素是:

        s,h = enum.next
          #=> ["Id = 123", {"Name"=>"abc"}] 
        s #=> "Id = 123" 
        h #=> {"Name"=>"abc"} 
        
        h.update([s.split(/\s*=\s*/)].to_h)
          #=> {"Name"=>"abc", "Id"=>"123"}
        

        等等。

        【讨论】:

          猜你喜欢
          • 2010-10-18
          • 2010-12-11
          • 1970-01-01
          • 2017-10-27
          • 2018-03-20
          • 1970-01-01
          • 2021-01-17
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多