Pregunta Dile al final de cada bucle en rubí


Si tengo un bucle como

users.each do |u|
  #some code
end

Donde los usuarios son un hash de múltiples usuarios. ¿Cuál es la lógica condicional más fácil de ver si está en el último usuario en el hash de los usuarios y solo desea ejecutar código específico para ese último usuario, por lo que algo así como

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

Gracias


75
2017-10-22 20:30


origen


Respuestas:


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

124
2017-10-22 20:34



Si se trata de una situación de ambos, donde aplicas algún código a todos pero el último usuario y luego algún código único para solamente el último usuario, una de las otras soluciones podría ser más apropiada.

Sin embargo, parece que está ejecutando el mismo código para todos los usuarios, y algunos adicional código para el último usuario. Si ese es el caso, esto parece más correcto, y establece más claramente su intención:

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

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

36
2017-10-22 20:39



Creo que el mejor enfoque es:

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

17
2017-10-25 16:53



¿Has probado? each_with_index?

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

8
2017-10-22 20:35



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

5
2017-10-22 20:38



A veces me parece mejor separar la lógica en dos partes, una para todos los usuarios y otra para la última. Entonces haría algo como esto:

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

method_for_all_users users.last
method_for_last_user users.last

3
2018-04-30 09:07



También puede usar el enfoque de @meager para una situación de "o bien", donde está aplicando un código a todos menos al último usuario y luego a un código único para el último usuario.

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

¡De esta manera no necesitas un condicional!


3
2017-09-16 13:34



Otra solución es rescatar de StopIteration:

user_list = users.each

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

1
2017-10-11 00:15



No hay un último método para hash para algunas versiones de 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

0
2017-07-23 07:06