On Dec 23, 6:04 am, Nicolas Buduroi <[email protected]> wrote:
> Hi, today I needed to use the map function on multiple collections
> which didn't had all the same length. In this case, it returns a
> sequence of the size of smallest one. But the problem I was facing was
> required to map until the end of the longest, padding the smaller ones
> with a default value. I came up with this:
>
> (defn mappad [f val & colls]
> (let [longest (apply max (map count colls))
> colls (map #(if (< (count %) longest)
> (concat % (repeat val))
> %) colls)]
> (apply (partial map f) colls)))
>
> user> (mappad #(+ %1 %2 %3) 0 [1] [2 3] [4 5 6])
> (7 8 6)
>
> Is there a better way?
Another, rather radical approach is to re-implement map with intrinsic
padding support (obviously based on clojure.core/map):
(defn map-longest
"Returns a lazy sequence consisting of the result of applying f to
the
set of first items of each coll, followed by applying f to the set
of second items in each coll, until *all* of the colls are
exhausted.
Missing items in exhausted colls are replaced with pad. Function
f should accept number-of-colls arguments."
([f pad coll]
(map f coll))
([f pad c1 c2]
(lazy-seq
(let [s1 (seq c1) s2 (seq c2)]
(when (or s1 s2)
(let [s1 (or s1 [pad])
s2 (or s2 [pad])]
(cons (f (first s1) (first s2))
(map-longest f pad (rest s1) (rest s2))))))))
([f pad c1 c2 c3]
(lazy-seq
(let [s1 (seq c1) s2 (seq c2) s3 (seq c3)]
(when (or s1 s2 s3)
(let [s1 (or s1 [pad])
s2 (or s2 [pad])
s3 (or s3 [pad])]
(cons (f (first s1) (first s2) (first s3))
(map-longest f pad (rest s1) (rest s2) (rest
s3))))))))
([f pad c1 c2 c3 & colls]
(let [step (fn step [cs]
(lazy-seq
(let [ss (map seq cs)]
(when (some identity ss)
(let [ss (reduce #(conj %1 (or %2 [pad])) []
ss)]
(cons (map first ss) (step (map rest
ss))))))))]
(map #(apply f %) (step (conj colls c3 c2 c1))))))
Of course, this solution results in lots of code duplication, looks
rather unwieldy and is less general than Heinz' solution. I'm curious:
Does it have any merits that could make its use worthwhile?
--
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