1

我正在尝试创建一个值作为数组的哈希。我正在向这些数组中添加元素,但由于某种原因,哈希在运行后变为空。我不知道为什么。这是我的代码

def function(words)
  hash = Hash.new([])  # default value of empty list
  words.each do |word|
    sorted = word.chars.sort.join  # sort the string
    hash[sorted] << word
    ## hash becomes empty here
  end
  return hash
end

puts function ['cars', 'for', 'potatoes', 'racs', 'four']

我是 Ruby 新手,我不知道为什么哈希会自行清空。我在 Python 中用相同的逻辑编写了一个类似的算法,它工作得非常好。有什么建议么?

4

2 回答 2

1

问题是您提供的默认哈希值是一个可变值(部分,至少 - 见下文),您需要改用Hash.new's block 参数:

hash = Hash.new { |h, k| h[k] = [] }

你得到正确的结果:

function ['cars', 'for', 'potatoes', 'racs', 'four']
#=> {"acrs"=>["cars", "racs"],
#    "for"=>["for"],
#    "aeoopstt"=>["potatoes"],
#    "foru"=>["four"]}

你所拥有的问题是hash[sorted]返回[],但从未真正分配给它。因此,您更改了数组,但从不将其放入哈希中。如果你+=改用(离开你的Hash.new([]),你可以这也有效:

hash[sorted] += [words]
于 2013-01-20T06:26:11.793 回答
-2

将值分配给散列键=

您可以通过替换hash[sorted] << word为以下内容轻松修复代码:

hash[sorted] = word

这是使原始代码工作真正需要的唯一更改。考虑:

def function(words)
  hash = Hash.new([])
  words.each do |word|
    sorted = word.chars.sort.join
    hash[sorted] = word
  end
  return hash
end

返回:

function %w[cars for potatoes racs four]
# => {"acrs"=>"racs", "for"=>"for", "aeoopstt"=>"potatoes", "foru"=>"four"}

几乎如你所料。在您发布的示例中,word是一个字符串,而不是一个数组。如果您不想只修复分配,还想将哈希值转换为数组,请参阅下面的建议重构。

你的代码重构

有很多方法可以清理你原来的方法。例如,这是重构代码的一种方法,使其更符合习惯且更易于阅读。

def sort_words words
  hash = {}
  words.map { |word| hash[word.chars.sort.join] = Array(word) }
  hash
end

sort_words %w[cars for potatoes racs four]
# => {"acrs"=>["racs"], "for"=>["for"], "aeoopstt"=>["potatoes"], "foru"=>["four"]}

其他重构当然是可能的——Ruby 是一种非常灵活和富有表现力的语言——但这应该会让你走上正确的道路。

于 2013-01-20T06:21:24.453 回答