gpt4 book ai didi

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

转载 作者:数据小太阳 更新时间:2023-10-29 08:44:29 24 4
gpt4 key购买 nike

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

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 你用来修改 frequencies 的 hash 也被修改了。

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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com