【问题标题】:Please help correct my misunderstanding of this collection iteration, matching and deletion:请帮助纠正我对这个集合迭代、匹配和删除的误解:
【发布时间】:2021-07-31 07:40:42
【问题描述】:

我正在尝试遍历字符串数组并删除第一个字母不是元音的字符串。我知道有更简洁的方法可以实现这一点,例如#select,但我不明白为什么以下不起作用。有人可以解释一下这段代码有什么问题吗:

def delete_unless_1st_letter_is_vowel(array)
  array.each do |element|
    first_letter = element[0]
    if !first_letter.match?(/[aeiou]/)
      array.delete(element)
    end
  end
end

array = %w(knit taleb know high london alpha)

返回;

taleb
high
alpha

我觉得它应该删除除alpha 之外的所有数组元素。我误会了什么?

【问题讨论】:

  • 旁白:我建议将if !first_letter.match?(/[aeiou]/); array.delete(element); end 替换为array.delete(element) unless first_letter.match?(/[aeiou]/)array.delete(element) if first_letter.match?(/[aeiou]/).nil?

标签: ruby iteration


【解决方案1】:

那是因为您在迭代 array 的同时删除了它的元素;

第一次迭代:

element = "knit"
array = ["knit", "taleb", "know", "high", "london", "alpha"]

你去掉“knit”,剩下的数组是["taleb", "know", "high", "london", "alpha"]

第二次迭代。该块继续工作,但现在轮到从array 持有的当前值产生第二个元素,即“知道”;

element = "know"
array = ["taleb", "high", "london", "alpha"]

第三次迭代。同样的故事,现在轮到产生第三个元素,它现在指向“london”:

element = "london"
array = ["taleb", "high", "alpha"]

第四次迭代。没有第四次迭代,您删除的元素数量与当前索引相同。

当你使用每个时,它会返回接收者,所以你会得到["taleb", "high", "alpha"]


为了简单起见,我认为在这种情况下grep就足够了:

def delete_unless_1st_letter_is_vowel(array)
  array.grep(/^[aeiou]/)
end

并且为了避免改变对象,即使编程语言让你去做。

【讨论】:

  • 非常感谢@Sebastian Palma,您对问题的有用说明让我了解现在发生了什么,即#each 迭代沿着数组内容索引移动,但是因为我告诉它删除主题元素(有条件地),在下一次迭代中它跳过考虑“下一个”主题元素,因为它们都向左移动了一个位置,因为在最后一次迭代中考虑的前面的一个位置被删除了。感谢您花时间解释。
猜你喜欢
  • 2021-04-23
  • 1970-01-01
  • 2021-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-17
  • 2013-06-15
相关资源
最近更新 更多