0

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

这是我的代码

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
4

4 回答 4

2

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

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

将返回a字符串中 s的数量

"asdfa".frequency #=> 2

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

于 2013-11-07T23:57:29.023 回答
1

这是我使用的版本,它是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 模块。这是一个代码示例,与类非常相似,但更简洁:

#!/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')

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

于 2013-11-08T00:16:47.937 回答
1

与其使用一个非常长的、非 DRY 的方法来迭代你的对象 26 次,不如使用一些 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.html http://ruby-doc.org/core-2.0.0/String.html

于 2013-11-08T08:06:42.857 回答
1

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

class String 
  def frequency
    chars.each_with_object(Hash.new(0)) do |char, h|
      h["#{char.upcase}:"] += 1 if char[/[[:alpha:]]/]
    end
  end
end
于 2013-11-12T13:27:16.683 回答