Other than loop .. recur, what is the best Clojure construct to use so that while traversing a sequence of sequences (sos), the processing can stop if a result is found?
Here are the details:
I have a lazy sequence returned from clojure-csv, an sos.
There is a value at a given position (index) in each sequence within the sos.
I keep looking at that position in each sequence until the value is found or the end of sos is reached.
If the value is found, I want to stop processing the sos.
The only thing I can think of is using a for with when and an into to retain the match, but the sequence processing won't stop, or use filter.
However, I believe I can use something better, but I'm stuck as to what that would be.
Thanks.
I prefer take-while for such tasks and if the key is at a fixed Index nth could match for it.
(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])
You could then map your processing function over the resulting sequence.
How about this?
(defn find-first [pred col]
(first (filter pred col)))
Then you can do this as an example:
(find-first #(< % 5) coll)
You should be able to make a predicate that works with a sequence of sequences.
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
for
with :while
can be used like:
(for [s sos :while (not (= (nth s index) val))]
s) ;;or do something with s
When just searching for the first occurence, I would use drop-while
. Indeed, filter
will process the whole sequence which is not useful. (and what if you want to use infinite sequences ?)
EDIT: Don't take this into account. Indeed, filter
returns a lazy sequence.
(defn find-first
[pred coll]
(first (drop-while #(not (pred %)) coll))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With