Gabriel Southern
Gabriel Southern

Reputation: 10063

How do I iterate to the next element in Ruby?

Is there a way to get the next element in a loop without starting from the beginning of the loop?

I know that next allows for iterating to the next element, but it starts at the beginning of the loop. I want to get the next element and continue to the next statement in the loop.

I am parsing a text file that is structured as follows:

element 1
part 1
part 2

element 2
part 1
part 2

Note that there are eleven parts per element, so this is just an example. Also, sometimes there are lines that are stripped out during parsing, so I don't think I can advance by a fixed number of elements for each loop iteration.

I read all of the text into an array and then I want to process each line using something like:

text.each do |L|
  #if L is new element create object to store data
  #parse next line store as part 1
  #parse next line store as part 2
end

I know how to do this with a while loop and a C-like coding style where I explicitly index into the array and increment the index variable by the amount I want each time, but I'm wondering if there is a Ruby way to do this. Something analogous to next but that would continue from the same point in the loop, just with the next element, rather than starting from the beginning of the loop.


Edit:

Here is a simplified example of how I could solve this problem with a while loop:

text = ["a", "b", "c", " ", " ", "d", "e", "f"]
i = 0
while i < text.length do
  if text[i] == " " then
    i += 1
  else
    a = text[i]
    b = text[i+1]
    c = text[i+2]
    puts a + b + c
    i += 3
  end
end

Note the actual code I'm writing is more complicated. I was trying to come up with the simplest example here that would illustrate what I want to do.

Upvotes: 1

Views: 3230

Answers (2)

Confusion
Confusion

Reputation: 16841

Taking the suggestion of @Phrogz in the comments and running with it:

def handle_sequence(sequence)
  puts sequence.join
end

text = ["a", "b", "c", " ", " ", "d", "e", "f"]
sequences = text.split(" ")
sequences.reject! {|sequence| sequence.empty?}
sequences.each {|sequence| handle_sequence(sequence)}

I separated the handle_sequence into a method because I imagine you'll want to do something else than just concatenate and print the elements to stdout.

BTW, I didn't downvote, just asked for clarification

Upvotes: 1

Linuxios
Linuxios

Reputation: 35783

Simple. Change each to each_with_index, and use the index:

text.each_with_index do |L, i|
  #Get next element
  text[i + 1]
end

However, your specific problem has a much better solution. Use each_slice:

text.each_slice(num_of_parts_to_element + 1) do |element|
  element[0] #element 1
  element[1..-1].each do |part|
    #Iterate over the parts
  end
end

Upvotes: 3

Related Questions