9 votes

Comment arrêter l'itération d'une séquence lorsqu'une condition est remplie ?

À part loop .. recur, quelle est la meilleure construction Clojure à utiliser pour que, tout en parcourant une séquence de séquences (sos), le traitement puisse s'arrêter si un résultat est trouvé ?

Voici les détails :

J'ai une séquence paresseuse retournée par clojure-csv, un sos.

Il existe une valeur à une position donnée (index) dans chaque séquence de l'OS.

Je continue à regarder cette position dans chaque séquence jusqu'à ce que la valeur soit trouvée ou que la fin de sos soit atteinte.

Si la valeur est trouvée, je veux arrêter le traitement du sos.

La seule chose à laquelle je pense est d'utiliser un for avec when et un into pour conserver la correspondance, mais le traitement de la séquence ne s'arrête pas, ou d'utiliser un filtre.

Cependant, je crois que je peux utiliser quelque chose de mieux, mais je ne sais pas ce que ce serait.

Merci.

9voto

Arthur Ulfeldt Points 45059

Je préfère take-while pour de telles tâches et si la clé est à un indice fixe, nth pourrait correspondre. nième indice pourrait correspondre.

(take-while #(not= (nth % index) key) sos)

user> (def sos [[1 2 3] [4 5 6] [7 8 9] [10 11 12]])
#'user/sos
user> (take-while #(not= (nth %  2) 9) sos)
([1 2 3] [4 5 6])

Vous pouvez ensuite faire correspondre votre fonction de traitement à la séquence résultante.

5voto

Kyle Points 13512

Que pensez-vous de ça ?

(defn find-first [pred col]
  (first (filter pred col)))

Alors vous pouvez faire ceci à titre d'exemple :

(find-first #(< % 5) coll)

Vous devriez être capable de créer un prédicat qui fonctionne avec une séquence de séquences.

user=> (defn find-first [pred col]
  (first (filter pred col)))
#'user/find-first
user=> (find-first #(> % 10) '(1 5 8 2 15 20 31 5 1))
15

4voto

Ankur Points 23539

for avec :while peut être utilisé comme :

(for [s sos :while (not (= (nth s index) val))]  
     s) ;;or do something with s

1voto

thoferon Points 2776

Pour la recherche de la première occurrence, j'utiliserais drop-while . En effet, filter traitera la séquence entière, ce qui n'est pas utile. (et que faire si l'on veut utiliser des séquences infinies ?)

EDITAR : Ne tenez pas compte de cela. En effet, filter renvoie une séquence paresseuse.

(defn find-first
  [pred coll]
  (first (drop-while #(not (pred %)) coll))

1voto

Daniel Compton Points 343

Je pense some convient parfaitement à cette fin.

"Renvoie la première valeur logique vraie de (pred x) pour tout x sur coll , else nil. Un idiome commun est d'utiliser un ensemble comme prédiction, par exemple ceci retournera :fred si :fred est dans la séquence, sinon c'est nul : (some #{:fred} coll) "

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