(filter-split #{\a\e\i\o\u} "is this not pung?") => [(\i \i \o \u)
(\s \space \t \h \s \space \n \t \space \p \n \g \?)]
(filter-split even? (range 10)) => [(0 2 4 6 8) (1 3 5 7 9)]
Aloha,
David Sletten
>
> That's the beauty of this language - there are many ways to skin
> the cat!
Hmmm...I'm not sure what I'll do with a skinless cat. :)
> Here's a version using reduce...
>
> (defn filt-split [pred col]
> (reduce (fn [[a b] x] (if (pred x) [(conj a x) b] [a (conj b x)]))
> [[] []] col))
>
> (filt-split even? [1 2 3 4 5 6 7 8])
> [[2 4 6 8] [1 3 5 7]]
>
I like that a lot. As long as the repeated creation of the ephemeral
vectors isn't too expensive.
> But when you look at separate in clojure.contrib.seq-utils its simple
> and elegant;
> (defn separate [f s]
> [(filter f s) (filter (complement f) s)])
>
This is exactly what I'm trying to avoid. I don't want to traverse
the collection twice.
Aloha,
David Sletten
> check the discussion with the subject, "time lies, even with
> doall". We came up with something like the following, but some
> name change change tweaks were suggested. This thing takes a pred
> and a collection and returns a list of two collections -- one that
> passes the pred, and one that fails.
>
> (defn filt-rem [pred coll]
> (loop [l1 () l2 () [f & r] coll]
> (if f
> (if (pred f)
> (recur (conj l1 f) l2 r)
> (recur l1 (conj l2 f) r))
> (list l1 l2))))
>
>
This is almost identical to what I posted. However, is this the
intended behavior?
(filt-rem identity '(true nil false 8)) => ((true) ())
(filt-split identity '(true nil false 8)) => [[true 8] [nil false]]
(filt-rem even? (range 10)) => ((8 6 4 2 0) (9 7 5 3 1))
(filter-split even? (range 10)) => [(0 2 4 6 8) (1 3 5 7 9)]
> (defn filter-split [pred coll]
> (loop [trues '() falses '() coll coll]
> (cond (empty? coll)
> (vector (reverse trues) (reverse falses))
> (pred (first coll))
> (recur (cons (first coll) trues) falses (rest coll))
> :else
> (recur trues (cons (first coll) falses) (rest coll)))))
Aloha,
David Sletten
That's the beauty of this language - there are many ways to skin the cat!
Here's a version using reduce...
(defn filt-split [pred col]
(reduce (fn [[a b] x] (if (pred x) [(conj a x) b] [a (conj b x)]))
[[] []] col))
(filt-split even? [1 2 3 4 5 6 7 8])
[[2 4 6 8] [1 3 5 7]]
But when you look at separate in clojure.contrib.seq-utils its simple
and elegant;
(defn separate [f s]
[(filter f s) (filter (complement f) s)])
Rgds, Adrian.
- Afficher le texte des messages précédents -
(filt-rem identity '(true nil false 8)) => ((true) ())
(filt-split identity '(true nil false 8)) => [[true 8] [nil false]]
(filt-rem even? (range 10)) => ((8 6 4 2 0) (9 7 5 3 1))
(filter-split even? (range 10)) => [(0 2 4 6 8) (1 3 5 7 9)]
This is exactly what I'm trying to avoid. I don't want to traverse
the collection twice.
Am 08.03.2009 um 11:44 schrieb Adrian Cuthbertson:
> that's a bit slower than both the previous versions. The reduce
> version does only apply the pred once per item I think?
unzip-with is lazy, the reduce version is not. I would
prefer laziness over speed.
Sincerely
Meikel
Sincerely
Meikel