web-dev-qa-db-fra.com

Dites la fin d'une boucle .each dans ruby

Si j'ai une boucle comme

users.each do |u|
  #some code
end

Où utilisateurs est un hachage de plusieurs utilisateurs. Quelle est la logique conditionnelle la plus simple pour voir si vous êtes sur le dernier utilisateur dans le hachage des utilisateurs et que vous souhaitez uniquement exécuter du code spécifique pour ce dernier utilisateur, donc quelque chose comme

users.each do |u|
  #code for everyone
  #conditional code for last user
    #code for the last user
  end
end
79
Splashlin
users.each_with_index do |u, index|
  # some code
  if index == users.size - 1
    # code for the last user
  end
end
135
Raphomet

Si c'est une situation soit/ou, où vous appliquez du code à tous mais le dernier utilisateur puis du code unique à seulement le dernier utilisateur, l'un de l'autre des solutions pourraient être plus appropriées.

Cependant, vous semblez exécuter le même code pour tous les utilisateurs et un code supplémentaire pour le dernier utilisateur. Si tel est le cas, cela semble plus correct et indique plus clairement votre intention:

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

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

Je pense qu'une meilleure approche est:

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

Avez-vous essayé each_with_index?

users.each_with_index do |u, i|
  if users.size-1 == i
     #code for last items
  end
end
10
Teja Kantamneni
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
6
DigitalRoss

Vous pouvez utiliser l'approche de @ meager également pour une situation soit/ou, où vous appliquez du code à tous sauf au dernier utilisateur, puis du code unique au dernier utilisateur uniquement.

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 cette façon, vous n'avez pas besoin d'un conditionnel!

3
coderuby

Parfois, je trouve préférable de séparer la logique en deux parties, une pour tous les utilisateurs et une pour la dernière. Je ferais donc quelque chose comme ceci:

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
xlembouras

Une autre solution consiste à sortir 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
ricardokrieg

Il n'y a pas de dernière méthode de hachage pour certaines versions 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