Dear Clojure Group,
In the style of *take-while* and *drop-while* I wrote two functions* take-by
* and *drop-by* that take an arbitrary function f instead of a predicate and
return a lazy sequence based on comparing the result of (f item) of
successive items in the collection.
However, whenever I need to compare adjacent items of a collection, I
quickly get lost and the result always looks like a hack. Here, this is
especially true for the implementation of *drop-by*:
(defn take-by [f coll]
"Starting from the first item in coll,
returns a lazy sequence of items for which (f item)
returns the same result."
(lazy-seq
(when-let [s (seq coll)]
(let [x (first s)]
(cons x (take-by f (when-let [y (second s)]
(if (= (f x) (f y))
(rest s)
nil))))))))
;; (take-by (partial + 2) [])
;; ()
;; (take-by (partial + 2) [2 2 2 3 3 4 4])
;; (2 2 2)
(defn drop-by [f coll]
"Returns a lazy sequence of the items in coll starting
from the first item for which (f item) returns the same result."
(lazy-seq
(let [s (seq coll), x (first s), y (second s)]
(if (and s y)
(if (= (f x) (f y))
(drop-by f (rest (rest s)))
(rest s))
s))))
;; (drop-by (partial + 2) [])
;; ()
;; (drop-by (partial + 2) [2 2 2 3 3 4])
;; (3 3 4)
I am sure there is a standard *functional* way of comparing adjacent items
in a coll and would be glad if someone could point me to it.
Also, any suggestions of making my code a little bit more idiomatic are
highly welcome!
Best regards,
Stefan
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en