我在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
答案 0 :(得分:2)
听起来你在谈论self
,这是引用当前对象的ruby关键字。请注意,如果您只是调用该方法,则会隐含self
。所以要使用你的例子
class String
def frequency
count('a')
end
end
将返回字符串
中a
的数量
"asdfa".frequency #=> 2
只是一个注释,但您当前的方法非常重复,您可能想要利用循环来减少代码量。你也不算大写字母:)
答案 1 :(得分: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 module。这是一个代码示例,非常类似于类但更干净的imho:
#!/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')
模块更适合在项目中添加自己的类,避免名称冲突和创建混合。
答案 2 :(得分: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
答案 3 :(得分: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