正在更新 Ruby 中的哈希值

Updating Hash value in Ruby

我想做的是将一堆用户输入的字符串推送到散列键中,用空格分隔,并按照输入顺序从 0 开始为每个键分配一个数值。例如;

用户输入:"a s d f b"

结果:

a => 0
b => 1
c => 2
d => 3
f => 4
b => 5

但是我的代码只输出0没有递增,请看下面我的代码;

puts "Please enter data:"
text = gets.chomp
words = text.split(" ")
    frequencies = Hash.new(0)

words.each do |k|
    frequencies[k] += 1
end

frequencies.each do |x,y|
    puts x + " " + y.to_s
end

谁能看出上面的代码有什么问题?

这个Hash中每个键的默认值是0,所以

frequencies[k] += 1

您正在将(不存在的键的)每个值从 0 递增到 1

一个简单的解决方法是使用外部计数器作为值:

counter = 0
words.each do |k|
    frequencies[k] = counter
    counter += 1
end

您的代码无效,因为

frequencies[k] += 1

喜欢

frequencies[k]    = frequencies[k] + 1
# ^ set new value   ^ get default value (i.e. 0)

默认值永远不会改变,因此每个键都获得相同的默认值 0 并对其加一。

您可以每次显式增加默认值

words.each do |k|
  frequencies[k] = frequencies.default += 1
end

但我认为更 Rubyish 的解决方案是使用键的索引(因为那是 "numerical values" 的意思)。 each_with_index 为您提供每个键及其对应的索引,to_h 将这些对转换为哈希。

frequencies = text.split.each_with_index.to_h

egwspiti 是正确的,旧版本的 Ruby 没有 Enumerable#to_h。在那种情况下你可以做

words.each_with_index do |k, i|
    frequencies[k] = i
end

frequencies 似乎是描述中变量名的错误选择。

任何你不能的理由

words = "foo bar baz"
=> "foo bar baz"
words.split.map.with_index.to_h
=> {"foo"=>0, "bar"=>1, "baz"=>2}