【问题标题】:How to convert array like this ["John,Doe,11222019", "Mark,King,11232019", "Angle,Darma,11242019"] to Array of hash Ruby如何将这样的数组 ["John,Doe,11222019", "Mark,King,11232019", "Angle,Darma,11242019"] 转换为哈希 Ruby 数组
【发布时间】:2019-07-14 23:00:39
【问题描述】:

如何转换数组:

["John,Doe,11222019", "Mark,King,11232019", "Angle,Darma,11242019"]

使用 Ruby 像这样的哈希数组:

[
  { :name => "John Doe", :number => 11222019 },
  { :name => "Mark King", :number => 11232019 },
  { :name => "Angle Darma", :number => 11242019 },
] 

非常感谢!

【问题讨论】:

    标签: arrays ruby object hash each


    【解决方案1】:

    你可以像下面这样简单,

    array.map { |x| [:name, :number].zip(x.sub(',', ' ').split(',')).to_h }
    
    # => [{:name=>"John Doe", :number=>11222019}, {:name=>"Mark King", :number=>11232019}, {:name=>"Angle Darma", :number=>11242019}] 
    

    【讨论】:

    • 非常感谢!在 ruby​​ 版本 2.4、2.5、2.6 中运行良好。救了我的命!
    【解决方案2】:

    使用 Ruby 2.6.1 Object#then 的选项:

    ary = ["John,Doe,11222019", "Mark,King,11232019", "Angle,Darma,11242019"]
    
    ary.map { |s| s.split(',').then{ |a| {name: a.first(2).join(' ') , number: a.last.to_i } } }
    

    对于 Ruby 2.5.2 Object#yield_self

    ary.map { |s| s.split(',').yield_self{ |a| {name: a.first(2).join(' ') , number: a.last.to_i } } }
    

    都返回:

    #=> [{:name=>"John Doe", :number=>11222019}, {:name=>"Mark King", :number=>11232019}, {:name=>"Angle Darma", :number=>11242019}]
    

    【讨论】:

    • 非常感谢!在 ruby​​ 版本 2.5、2.6 中运行良好
    【解决方案3】:
    arr = ["John,Doe,11222019", "Mark,King,11232019",
           "Angle,Darma,11242019"]
    
    arr.map do |s|
      {name: s[/.+(?=,)/].tr(',',' '), number: s[/\d+/].to_i}
    end
      #=> [{:name=>"John Doe",    :number=>11222019},
      #    {:name=>"Mark King",   :number=>11232019},
      #    {:name=>"Angle Darma", :number=>11242019}] 
    

    步骤如下。 Enumerable#maparr 的第一个元素传递给块,块变量s 被设置为等于它的值:

    s = arr.first
      #=> "John,Doe,11222019"
    

    然后执行块计算:

    a = s[/.+(?=,)/]
      #=> "John,Doe"
    

    这使用方法String#[] 和正则表达式/.+(?=,)/(?=,) 是一个正向预测,它要求匹配项后面紧跟一个逗号。因为默认情况下匹配是 greedy,所以前瞻匹配 s 中的最后一个逗号。

    b = a.tr(',',' ')
      #=> "John Doe"
    

    这使用方法String#tr。或者,可以使用a.sub(',',' ')

    c = s[/\d+/]
      #=> "11222019" 
    d = c.to_i
      #=> 11222019 
    

    块然后返回:

    { name: c, number: d }
      #=> {:name=>"11222019", :number=>11222019} 
    

    这是s 映射到的对象。 arr 的其余两个值被传递给块并执行类似的计算。

    【讨论】:

      【解决方案4】:

      a = ["John,Doe,11222019", "Mark,King,11232019", "Angle,Darma,11242019"]

      类似的东西

      a.map do |f|
        f = f.split(',')
        { name: "#{f[0]} #{f[1]}", number: f[2].to_i }
      end
      

      【讨论】:

      • a, b, c = f.split(','){ name: "#{a} #{b}", number: c.to_i }
      【解决方案5】:
      arr = ["John,Doe,11222019", "Mark,King,11232019", "Angle,Darma,11242019"]
      
      arr.map do |item|
        chunks = item.split(",")
        {name: chunks[0...-1].join(" "), number: chunks[-1]}
      end
      

      索引 [0...-1] 允许您在名称部分(中间名或 2 个姓氏)中拥有可变数量的项目,这很常见。

      【讨论】:

      • 谢谢。运行良好!
      猜你喜欢
      • 2021-10-16
      • 2010-12-11
      • 1970-01-01
      • 1970-01-01
      • 2021-11-25
      • 1970-01-01
      • 2021-01-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多