arrays - 使用 #each_with_index 更改数组时出现奇怪的结果

标签 arrays ruby

我正在尝试编写一些代码,该代码将循环遍历字符串数组,清理条目,然后将清理后的条目添加到跟踪每个单词出现频率的哈希中。这是我的第一个解决方案:

puts("Give me your text.")
text = gets.chomp

words = text.split
frequencies = Hash.new(0)
words.map! do |word|
  word.tr("\",.", "")
end
words.each do |word|
  frequencies[word] += 1
end

它工作得很好,但是循环遍历数组两次感觉非常低效,所以我一直在尝试找到一种方法来完成它,并偶然发现了以下内容:

puts("Give me your text.")
text = gets.chomp

words = text.split
frequencies = Hash.new(0)
words.each_with_index do |word, index|
  words[index].tr!("\",.", "")
  frequencies[word] += 1
end

根据我对each_with_index的理解,这不应该起作用,但不知何故它确实起作用,并且哈希接收每个字符串的干净版本:https://repl.it/B9Gw 。这里发生了什么?有没有不同的方法来解决这个问题而不循环两次?

编辑:经过一番阅读后,我能够通过以下方式仅使用一个循环来解决问题:

puts("Give me your text.")
text = gets.chomp

words = text.split
frequencies = Hash.new(0)
for i in 0..words.length-1
  words[i].tr!("\",.", "")
  frequencies[words[i]] += 1
end

但是,这更多的是 JS 或 C++ 解决方案,看起来不像惯用的 Ruby。还有其他选择吗?另外,为什么 each_with_index 方法甚至有效?

最佳答案

您正在使用 String#tr! 方法,该方法会破坏性地修改字符串,而不是返回新字符串。事实上,您再次在哈希上查找它(使用 words[index])不会改变任何内容,因为字符串对象仍然相同 - 所以 word > 您用来修改频率的哈希值也会被修改。

And is there a different way to solve this problem without looping twice?

一个明显的方法是使用与您使用的相同的逻辑,但没有 with_index (无论如何,这在这里没有任何区别)。我建议使用非破坏性的 String#tr 而不是 String#tr!,以便更清楚哪些字符串已被清理,哪些尚未清理。

frequencies = Hash.new(0)
words.each do |word|
  cleaned = word.tr("\",.", "")
  frequencies[cleaned] += 1
end

如果您想明确进程的 map 阶段,并且仍然只循环一次,您可以利用 ruby​​ 的惰性枚举器:

frequencies = Hash.new(0)
cleaned_words = words.lazy.map { |word| word.tr("\",.", "") }

cleaned_words.each do |cleaned|
  frequencies[cleaned] += 1
end

在这里,即使我们先执行一个map,然后执行一个each,该集合也只被遍历一次,并且 ruby​​ 不会创建任何中间数组。

关于arrays - 使用 #each_with_index 更改数组时出现奇怪的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34325542/

相关文章:

ruby - ruby 脚本偶尔出现 "Permission denied @ rb_sysopen"

ruby - 如何获得符号链接(symbolic link)的目标?

ruby-on-rails - rails 应用程序中的 Stripe success_url 格式未创建正确的 URL

python - 从 Numpy 中的 N 个向量中找到所有唯一的(几乎)平行 3d 向量对的最快方法

arrays - 如何在 bool 数组上使用逻辑运算符?

android - 如何使用字节数组上传图像

ruby - 我如何在 Bluemix 中升级 Rubygems?

c - C中如何确定数组元素的个数?

python - 在 matlab 和 python 中创建迭代数组

ruby - Net::SFTP 传输模式(二进制与文本)