60 votes

Sautez sur l'itération en Énumérable#recueillir

(1..4).collect do |x|
  next if x == 3
  x + 1
end # => [2, 3, nil, 5]
    # desired => [2, 3, 5]

Si la condition pour l' next est atteint, collect met nil dans le tableau, alors que ce que je suis en train de faire est de mettre aucun élément dans le tableau renvoyé si la condition est remplie. Est-ce possible sans faire appel delete_if { |x| x == nil } sur le tableau retourné?

(À l'aide de Ruby 1.8.7; mon extrait de code est très abstrait)

80voto

Mladen Jablanović Points 22082

Il y a la méthode de Enumerable#reject qui sert juste à la fin:

(1..4).reject{|x| x == 3}.collect{|x| x + 1}

La pratique d'utiliser directement une sortie d'une méthode comme une entrée de l'autre est appelée méthode de chaînage et est très commun en Ruby.

BTW, map (ou collect) est utilisé pour le mappage direct de l'entrée énumérable à la sortie d'une. Si vous avez besoin de générer un nombre différent d'éléments, les chances sont que vous avez besoin d'une autre méthode de Enumerable.

Edit: Si vous êtes gêné par le fait que certains des éléments sont répétées deux fois, vous pouvez utiliser moins élégante solution basée sur inject (ou de ses semblables méthode nommée each_with_object):

(1..4).each_with_object([]){|x,a| a << x + 1 unless x == 3}

49voto

Benson Points 10705

Je voudrais simplement appeler .compact sur la résultante de la matrice, ce qui supprime toutes les instances de néant dans un tableau. Si vous souhaitez modifier le tableau existant (pas de raison de ne pas le faire), utilisez .compact!:

(1..4).collect do |x|
  next if x == 3
  x
end.compact!

5voto

Staelen Points 4666

juste une suggestion, pourquoi ne pas vous faire de cette façon:

result = []
(1..4).each do |x|
  next if x == 3
  result << x
end
result # => [1, 2, 4]

de cette façon, vous avez enregistré une autre itération de supprimer néant les éléments du tableau. espérons que cela aide =)

0voto

ALoR Points 2599

je suggère d'utiliser:

(1..4).to_a.delete_if {|x| x == 3}

au lieu de les recueillir + instruction suivante.

0voto

alxndr Points 729

Vous pouvait tirer de la prise de décision dans un helper, et l'utiliser via Enumerable#reduce:

def potentially_keep(list, i)
  if i === 3
    list
  else
    list.push i
  end
end
# => :potentially_keep

(1..4).reduce([]) { |memo, i| potentially_keep(memo, i) }
# => [1, 2, 4]

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X