【问题标题】:ruby string to hash conversionruby 字符串到哈希的转换
【发布时间】:2011-10-20 13:48:40
【问题描述】:

我有一个这样的字符串,

str = "uu@p, xx@m, yy@n, zz@m"

我想知道如何将给定的字符串转换为哈希。 (即我的实际要求是,有多少个值(在 @ 符号之前)有 m、n 和 p。我不想要计数,我需要一个确切的值)。这样输出会更好,

{"m" => ["xx", "zz"], "n" => ["yy"], "p" => ["uu"]}

有人可以帮帮我吗?

【问题讨论】:

    标签: ruby string hash


    【解决方案1】:

    直接复制/过去 IRB 会话:

    >> str.split(/, /).inject(Hash.new{|h,k|h[k]=[]}) do |h, s|
    ..   v,k = s.split(/@/)
    ..   h[k] << v
    ..   h
    ..   end
    => {"p"=>["uu"], "m"=>["xx", "zz"], "n"=>["yy"]}
    

    【讨论】:

    • 非常感谢@Michael。这是我所期望的。再一次,我对注入方法的力量感到兴奋。你能解释一下这部分“..inject(Hash.new{|h,k|h[k]=[]})..”吗?这有助于提高自己。
    • 很高兴为您提供帮助! :-) 如果您的问题得到充分回答,请接受它以便其他人知道。
    • 当然,我使用 Hash.new 的块形式(请参阅文档)注入一个默认值为空数组的哈希。
    【解决方案2】:

    为新手提供更简单的代码 :)

    str = "uu@p, xx@m, yy@n, zz@m"
    h = {}
    str.split(",").each do |x| 
       v,k = x.split('@')
       h[k] ||= []
       h[k].push(v)
    end
    
    p h
    

    【讨论】:

      【解决方案3】:

      FP 风格:

      grouped = str.split(", ").group_by { |s| s.split("@")[1] }
      Hash[grouped.map { |d, emails| [d, emails.map { |s| s.split("@")[0] }] }]
      
      #=> {"m"=>["xx", "zz"], "n"=>["yy"], "p"=>["uu"]}
      

      像往常一样,如果你使用Facets很酷的抽象,解决方案会更短更清晰(不需要安装整个库,只需将特定方法复制到你的扩展模块):

      require 'facets'
      str.split(", ").map_by { |s| s.split("@", 2).reverse }
      #=> {"m"=>["xx", "zz"], "n"=>["yy"], "p"=>["uu"]}
      

      Facets#map_by = group_by+map

      【讨论】:

      • 折叠(以及inject)功能对您来说还不够吗? ;-)
      • 我认为我更喜欢这个只是因为它不涉及将状态保存在临时变量中。
      • @迈克尔。让我们称之为“另一个 FP 风格的答案”。但是,请注意“h[k]
      • 对数组进行变异已经足够了。关于你提到的那条建议:我以前从未真正听说过,我经常使用 Haskell 和 Clojure。 :-) 无论如何,我喜欢你的回答,我是两个支持者之一。
      • @迈克尔。公平地说,在这种情况下,vanilla Ruby 没有合适的抽象(我的第一个 sn-p 分裂了两次,这在概念上很丑)。所以,我会选择你的注入或 Facets#map_by。
      猜你喜欢
      • 1970-01-01
      • 2015-03-20
      • 2015-04-02
      • 2010-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-06
      • 2014-09-24
      相关资源
      最近更新 更多