我正在解决的错误问题

时间:2014-09-04 03:42:02

标签: ruby hash each

这是我试图运行的代码,它计算传递给它的数组中字符的频率,这就是我得到的错误 frequency_string': undefined method每个' for" a":String(NoMethodError)。我不完全确定出了什么问题,因为这是应该工作的代码并且是给我的。对Ruby来说很新,并花了好几个小时试图自己解决这个问题。我会得到任何帮助。

def frequency_string(chars)
    frequencies = {}
    result = ""
    chars.each do |char|
        if frequencies.has_key? char then
            frequencies = 1
        else
            frequencies[char] += 1
        end
    end
    frequencies.each do |char, freq|
        result << char << freq
    end
    return result
end
data1 = ['a', 'b', 'c', 'c', 'd', 'a', '#', 'b', '#', 'a']
puts "Data 1: " + data1.join(' ')
puts
puts frequency_string(data1)

2 个答案:

答案 0 :(得分:0)

你有两个问题:

  • frequencies = 1应为frequencies[char] = 1。就目前而言,您将哈希转换为数字1
  • 您有frequency[char] = 1frequency[char] = 1撤消。

以下是您更正后的代码:

def frequency_string(chars)
  frequencies = {}
  result = ""
  chars.each do |char|
    if frequencies.has_key? char then
      frequencies[char] += 1
    else
      frequencies[char] = 1
    end
  end
  frequencies.each do |char, freq|
    result << char << freq.to_s
  end
  result
end
data1 = ['a', 'b', 'c', 'c', 'd', 'a', '#', 'b', '#', 'a']
puts "Data 1: " + data1.join(' ')
puts
puts frequency_string(data1)
  #=> a3b2c2d1#2

当您获得Ruby经验时,您会发现该语言允许您使用非常少的代码编写此类操作。这是一种方式:

def frequency_string(chars)
  chars.each_with_object({}) { |char,hash|
    hash[char] = (hash[char] ||= 0) + 1 }.to_a.flatten.join
end
puts frequency_string(data1)
  #=> a3b2c2d1#2

这可能看起来很复杂,但是在你发现它比你所写的更自然和简单之前不久。你现在不必担心这件事;我只是想让你体会一下你所期待的。

答案 1 :(得分:0)

chars.each do |char|
    if frequencies.has_key? char then
        frequencies = 1
    else
        frequencies[char] += 1
    end
end

应该是:

chars.each do |char|
    if frequencies.has_key? char
        frequencies[char] += 1
    else
        frequencies[char] = 1
    end
end

chars.each { |char| frequencies.has_key?(char) ? frequencies[char] += 1 : frequencies[char] = 1 }

你也可以这样:

group_by usage

irb(main):038:0> data1.group_by { |e| e }
=> {"a"=>["a", "a", "a"], "b"=>["b", "b"], "c"=>["c", "c"], "d"=>["d"], "#"=>["#", "#"]}
irb(main):041:0> data1.group_by { |e| data1.count(e) }
=> {3=>["a", "a", "a"], 2=>["b", "c", "c", "#", "b", "#"], 1=>["d"]} # it can be an optional if it can meet your demands
改善后:

irb(main):053:0> result = ''
=> ""
irb(main):054:0> data1.group_by { |e| e }.each { |e| result += e[0] + e[1].count.to_s }
=> {"a"=>["a", "a", "a"], "b"=>["b", "b"], "c"=>["c", "c"], "d"=>["d"], "#"=>["#", "#"]}
irb(main):055:0> result
=> "a3b2c2d1#2"

或使用inject

irb(main):040:0> data1.group_by { |e| e }.inject('') {|r, e| r + e[0] + e[1].count.to_s}
=> "a3b2c2d1#2"