Tell the end of a .each loop in ruby

Ruby on-RailsRubyLoopsEach

Ruby on-Rails Problem Overview


If i have a loop such as

users.each do |u|
  #some code
end

Where users is a hash of multiple users. What's the easiest conditional logic to see if you are on the last user in the users hash and only want to execute specific code for that last user so something like

users.each do |u|
  #code for everyone
  #conditional code for last user
    #code for the last user
  end
end

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

users.each_with_index do |u, index|
  # some code
  if index == users.size - 1
    # code for the last user
  end
end

Solution 2 - Ruby on-Rails

If it's an either/or situation, where you're applying some code to all but the last user and then some unique code to only the last user, one of the other solutions might be more appropriate.

However, you seem to be running the same code for all users, and some additional code for the last user. If that's the case, this seems more correct, and more clearly states your intent:

users.each do |u|
  #code for everyone
end

users.last.do_stuff() # code for last user

Solution 3 - Ruby on-Rails

I think a best approach is:

users.each do |u|
  #code for everyone
  if u.equal?(users.last)
    #code for the last user
  end
end

Solution 4 - Ruby on-Rails

Did you tried each_with_index?

users.each_with_index do |u, i|
  if users.size-1 == i
     #code for last items
  end
end

Solution 5 - Ruby on-Rails

h = { :a => :aa, :b => :bb }
h.each_with_index do |(k,v), i|
  puts ' Put last element logic here' if i == h.size - 1
end

Solution 6 - Ruby on-Rails

Another solution is to rescue from StopIteration:

user_list = users.each

begin
  while true do
    user = user_list.next
    user.do_something
  end
rescue StopIteration
  user.do_something
end

Solution 7 - Ruby on-Rails

You can use @meager's approach also for an either/or situation, where you're applying some code to all but the last user and then some unique code to only the last user.

users[0..-2].each do |u|
  #code for everyone except the last one, if the array size is 1 it gets never executed
end

users.last.do_stuff() # code for last user

This way you don't need a conditional!

Solution 8 - Ruby on-Rails

Sometimes I find it better to separate the logic to two parts, one for all users and one for the last one. So I would do something like this:

users[0...-1].each do |user|
  method_for_all_users user
end

method_for_all_users users.last
method_for_last_user users.last

Solution 9 - Ruby on-Rails

There are no last method for hash for some versions of ruby

h = { :a => :aa, :b => :bb }
last_key = h.keys.last
h.each do |k,v|
    puts "Put last key #{k} and last value #{v}" if last_key == k
end

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSplashlinView Question on Stackoverflow
Solution 1 - Ruby on-RailsRaphometView Answer on Stackoverflow
Solution 2 - Ruby on-Railsuser229044View Answer on Stackoverflow
Solution 3 - Ruby on-RailsAlter LagosView Answer on Stackoverflow
Solution 4 - Ruby on-RailsTeja KantamneniView Answer on Stackoverflow
Solution 5 - Ruby on-RailsDigitalRossView Answer on Stackoverflow
Solution 6 - Ruby on-RailsricardokriegView Answer on Stackoverflow
Solution 7 - Ruby on-RailscoderubyView Answer on Stackoverflow
Solution 8 - Ruby on-RailsxlembourasView Answer on Stackoverflow
Solution 9 - Ruby on-RailsSathianarayanan SundaramView Answer on Stackoverflow