Pavol Pľuta Pavol Pľuta - 10 months ago 56
Ruby Question

'Next' keyword misunderstood in specific Ruby code

I did a small programme to count words in the array:

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
if s[i] != " " and s[i-1] == " "
wis += 1

words += wis

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


Words in the array: 13

It works properly, but there's a one thing which I can't understand. I know that
keyword leaves the current iteration but I don't know how it exactly works right here. If I omit it from the code, Output would be
Words in the array: 14
. I know
can be replaced with
condition and that's the problem - I don't know how to define it.

  • Can you please explain me how does
    work in the code?

  • Can you give me the alternative solution for that
    condition without using

Thank you

Answer Source

As others have said, there are a lot of more elegant ways of writing a word count in Ruby. However, I'll try and answer your specific questions as there's still something to learn here.

As you've mentioned next leaves the current iteration. In your example it means that when both the i == 0 condition and the s[i] != " " condition are true then the next will execute and the if s[i] != " " and s[i-1] == " "... part will be skipped for that iteration.

The reason for getting a count of 14 words when you remove the next relies on knowing what happens when a negative index is used for a string. In this line:

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

when i is 0 this is equivalent to

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

s[-1] means the last character of the string. This is true for the line "fifth line " so the result is that the first word of that line is counted twice.

To replace the next with an else condition you'd need to arrange an alternative way for the if s[i] != " " and s[i-1] == " "... not to execute if i == 0 and s[i] != " " so something like:

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