【问题标题】:Merge a hash with the key/values of a string in ruby将哈希与 ruby​​ 中字符串的键/值合并
【发布时间】:2011-02-01 08:38:32
【问题描述】:

我正在尝试将哈希与 ruby​​ 中字符串的键/值合并。

h = {:day => 4, :month => 8, :year => 2010}
s = "/my/crazy/url/:day/:month/:year"
puts s.interpolate(h)

我发现的只是迭代键并替换值。但我不确定是否有更好的方法来做到这一点? :)

class String
  def interpolate(e)
    self if e.each{|k, v| self.gsub!(":#{k}", "#{v}")}
  end
end

谢谢

【问题讨论】:

    标签: ruby string hash merge


    【解决方案1】:

    “更好”可能是主观的,但这是一种只使用一次调用gsub的方法:

    class String
      def interpolate!(h)
        self.gsub!(/:(\w+)/) { h[$1.to_sym] }
      end
    end
    

    因此:

    >> "/my/crazy/url/:day/:month/:year".interpolate!(h)
    => "/my/crazy/url/4/8/2010"
    

    【讨论】:

    • 但是如果你有s="/my/crazy/url/:somethingelse/:month/:year"会发生什么?
    • 好吧,h[:nothashed] 给出了nil,所以它将替换为一个空字符串。你可以用h[$1.to_sym]||"default"之类的东西来解决这个问题
    【解决方案2】:

    这对我来说看起来不错,但另一种方法是使用 ERB:

    require 'erb'
    
    h = {:day => 4, :month => 8, :year => 2010}
    template = ERB.new "/my/crazy/url/<%=h[:day]%>/<%=h[:month]%>/<%=h[:year]%>"
    puts template.result(binding)
    

    【讨论】:

      【解决方案3】:

      另外的想法可能是扩展String#% 方法,使其知道如何处理Hash 参数,同时保留现有功能:

      class String
        alias_method :orig_percent, :%
        def %(e)
          if e.is_a?(Hash)
            # based on Michael's answer
            self.gsub(/:(\w+)/) {e[$1.to_sym]}
          else
            self.orig_percent e
          end
        end
      end
      
      s = "/my/%s/%d/:day/:month/:year"
      puts s % {:day => 4, :month => 8, :year => 2010}
      #=> /my/%s/%d/4/8/2010
      puts s % ['test', 5]
      #=> /my/test/5/:day/:month/:year
      

      【讨论】:

      • 谢谢姆拉登。这看起来很有希望
      【解决方案4】:

      无需重新发明 Ruby 内置插件:

      h = {:day => 4, :month => 8, :year => 2010}
      s = "/my/crazy/url/%{day}/%{month}/%{year}"
      puts s % h
      

      (注意这需要 Ruby 1.9+)

      【讨论】:

      • 仍然有很多 Ruby 1.8.x 脚本,但很高兴 1.9 终于实现了这样一个基本功能。
      猜你喜欢
      • 1970-01-01
      • 2014-06-15
      • 1970-01-01
      • 2012-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-13
      相关资源
      最近更新 更多