'Next' 关键字在特定 Ruby 代码中被误解

'Next' keyword misunderstood in specific Ruby code

我做了一个小程序来计算数组中的单词数:

array = ["first line",
     "second   line",
     "",
     "  fourth line   containing  a few  more words   ",
     "fifth line "]

words = 0

array.each do |s|
  wis = 0
  s.length.times do |i|
    if i == 0
      if s[i] != " "
        wis = 1
        next #HERE IT COMES.
      end
    end
    if s[i] != " " and s[i-1] == " "
      wis += 1
    end

  end
  words += wis
end

puts "Words in the array: #{words}"

输出:

Words in the array: 13

它工作正常,但有一件事我不明白。我知道 next 关键字离开当前迭代,但我不知道它在这里是如何工作的。如果我从代码中省略它,输出将是 Words in the array: 14。我知道 next 可以替换为 else 条件,这就是问题所在 - 我不知道如何定义它。

谢谢

说到next的使用,建议大家阅读this answer here

关于您的代码,我可以告诉您,学习 Ruby 需要您的编程方式有更大的改变。这不仅仅是使用 Ruby 语法的问题,也是探索 Ruby 简化事情的潜力的问题。

例如,您可以在没有任何 if 的情况下完成任务。

array = ["first line",
     "second   line",
     "",
     "  fourth line   containing  a few  more words   ",
     "fifth line "]

count = array.inject(0) { |c, item| c + item.strip.split(" ").count }

puts count

这会给你

13

正好是字数,根本没有if

这甚至不是最好的方法。我相信这可以做得更短。

正如其他人所说,在 Ruby 中有很多更优雅的写字数的方法。但是,我会尝试回答您的具体问题,因为这里还有一些东西需要学习。

如您所述,next 离开当前迭代。在您的示例中,这意味着当 i == 0 条件和 s[i] != " " 条件都为真时,next 将执行并且 if s[i] != " " and s[i-1] == " "... 部分将在该迭代中被跳过。

当您删除 next 时得到 14 个单词计数的原因依赖于知道当负索引用于字符串时会发生什么。在这一行中:

if s[i] != " " and s[i-1] == " "

i 为 0 时,这相当于

s[0] != " " and s[-1] == " "

s[-1]表示字符串的最后一个字符"fifth line " 行也是如此,因此结果是该行的第一个单词被计算了两次。

要将 next 替换为 else 条件,您需要安排另一种方法让 if s[i] != " " and s[i-1] == " "...i == 0 and s[i] != " " 时不执行,例如:

if i == 0 and s[i] != " "
  wis = 1
elsif s[i] != " " and s[i-1] == " "
  wis += 1
end

使用 "next" 关键字的简单示例

(1..10).each do |a|
   next if a.even?
   puts a
end

输出:-

1
3   
5
7
9

块中 next 的用法: 当块中使用 next 时,它会导致块立即退出,将控制返回给迭代器方法,然后迭代器方法可能会开始通过再次调用块进行新的迭代

Next 跳回到代码块的开头,在本例中跳转到下一个数组元素。

如何更好地做到这一点的最短可能答案是恕我直言

puts "Words in the array: #{array.join(' ').split(/\W+/).length}"
# Words in the array: 13

一些解释: 在处理字符串时,通常最好使用正则表达式,为了简单起见,我首先将所有数组元素组合成一个字符串:array.join(' ') space 用作分隔符以防止单词连接在一起。 这个字符串再次用 // 之间的正则表达式拆分,即 \W+ ,这意味着一系列非定界符字符(因此是一个单词)。 该数组的长度为 string/array.

中的单词数

编辑:使用扫描而不是拆分和计数而不是长度 8 缩短了两个字符:)

array.join(' ').scan(/\W+/).count