【问题标题】:Can I use methods for String class within the String class in Ruby?我可以在 Ruby 的 String 类中使用 String 类的方法吗?
【发布时间】:2013-11-07 23:52:43
【问题描述】:

我在 ruby​​ 中的字符串对象的新方法应该返回字符串中每个字符的计数的哈希值(从 .txt 文件中加载),我可能正在尝试以简单的方式进行操作,但是如果不传递对象,我似乎无法使其工作。我想知道是否有办法在不传递字符串的情况下做到这一点。任何帮助将不胜感激。

这是我的代码

class String
  def frequency
    Object.downcase
    Object.gsub("\n", " ")
    h = {}
    h["A:"] = Object.count('a')
    h["B:"] = Object.count('b')
    h["C:"] = Object.count('c')
    h["D:"] = Object.count('d')
    h["E:"] = Object.count('e')
    h["F:"] = Object.count('f')
    h["G:"] = Object.count('g')
    h["H:"] = Object.count('h')
    h["I:"] = Object.count('i')
    h["J:"] = Object.count('j')
    h["K:"] = Object.count('k')
    h["L:"] = Object.count('l')
    h["M:"] = Object.count('m')
    h["N:"] = Object.count('n')
    h["O:"] = Object.count('o')
    h["P:"] = Object.count('p')
    h["Q:"] = Object.count('q')
    h["R:"] = Object.count('r')
    h["S:"] = Object.count('s')
    h["T:"] = Object.count('t')
    h["U:"] = Object.count('u')
    h["V:"] = Object.count('v')
    h["W:"] = Object.count('w')
    h["K:"] = Object.count('x')
    h["Y:"] = Object.count('y')
    h["Z"] = Object.count('z')
return h
end
end

【问题讨论】:

    标签: ruby string hash metaprogramming


    【解决方案1】:

    听起来您在谈论self,它是引用当前对象的ruby 关键字。请注意,如果您只是调用该方法,则隐含 self。所以用你的例子

    class String
      def frequency
        count('a')
      end
    end
    

    将返回字符串中as 的数量

    "asdfa".frequency #=> 2
    

    请注意,但您当前的方法非常重复,您可能需要考虑利用循环来减少代码量。你也不算大写字母:)

    【讨论】:

    • 这就是为什么我尝试使用 .downcase 这样它会使所有的大写字母都变小,然后计算它们
    • 很公平,错过了那部分!
    【解决方案2】:

    与其将对象迭代 26 次的非常长的非 DRY 方法,不如使用一些 Ruby:

    def frequency
      Hash[downcase.gsub(/[^a-z]/,'').chars.group_by(&:to_s).map{|char, group| ["#{char.upcase}:", group.size]}]
    end
    

    如果您发现它更易于阅读(并在 API [1] 中查找方法),您可以将其拆分为单独的行:

    def frequency
      intermediate_variable = downcase
      intermediate_variable = intermediate_variable.gsub(/[^a-z]/,'') # only keep a-z characters
      intermediate_variable = intermediate_variable.chars.group_by(&:to_s) # split the string into its component characters and then group that array by the characters (run this on an array to see what it does :-)  could also have written it `.group_by{|e|e}`
      intermediate_variable = intermediate_variable.map{|char, group| ["#{char.upcase}:", group.size]} # map the array of grouped characters into an array of character and counts (formatting the 'character' how you would like your hash key configured
      Hash[intermediate_variable] # make a hash of the characters and their counts
    end
    

    [1]http://ruby-doc.org/core-2.0.0/Enumerable.htmlhttp://ruby-doc.org/core-2.0.0/String.html

    【讨论】:

    • 有没有将计数打印为 * 所代表的数字?
    • 嗯?我们为你做所有的功课吗? ;-) '*' * frequency
    【解决方案3】:

    这是我使用的版本,它是 Rosetta Letter Frequency 的完整副本:

    #!/usr/bin/env ruby
    def letter_frequency(string)
        freq = Hash.new(0)
        string.each_char.lazy.grep(/[[:alpha:]]/).map(&:upcase).each_with_object(freq) do |char, freq_map|
            freq_map[char] += 1
        end
    end
    

    在 ruby​​ 中,您可以打开类并添加方法,例如:

    class String
       def my_method
           my_method_code
       end
    end
    

    然后你只需调用方法string.my_method。但是,在您的情况下,我宁愿使用Ruby module。这是一个代码示例,与类非常相似,但更简洁:

    #!/usr/bin/env ruby
    
    module MyString
        def self.letter_frequency(string)
            freq = Hash.new(0)
            string.each_char.lazy.grep(/[[:alpha:]]/).map(&:upcase).each_with_object(freq) do |char, freq_map|
                freq_map[char] += 1
            end
            return freq
        end
    end
    
    p MyString.letter_frequency('absd')
    

    模块更适合将您自己的类添加到项目中,避免名称冲突和创建混入。

    【讨论】:

      【解决方案4】:

      我会像这样创建一个哈希:

      class String 
        def frequency
          chars.each_with_object(Hash.new(0)) do |char, h|
            h["#{char.upcase}:"] += 1 if char[/[[:alpha:]]/]
          end
        end
      end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-09-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-04
        • 2013-07-18
        • 2018-03-04
        • 1970-01-01
        相关资源
        最近更新 更多