Clojure map-longest
Here is a solution:
(defn map-longest
([fn missing-value-fn c1]
(map fn c1))
([fn missing-value-fn c1 & colls]
(lazy-seq
(when (not-every? empty? (conj colls c1))
(let [firsts (map first (conj colls c1))]
(cons
(apply fn (map #(if (nil? %) (missing-value-fn) %) firsts))
(apply map-longest
(conj (map rest colls) (rest c1) missing-value-fn fn))))))))
Test:
user=> (print (apply str
(map-longest #(str %1 \space %2 \space %3 \newline) #(identity "--")
["a1" "a2" "a3"] ["b1" "b2"] ["c1" "c2" "c3" "c4"])))
a1 b1 c1
a2 b2 c2
a3 -- c3
-- -- c4
nil
Note that I have taken the missing-value-fn
approach rather than the missing-value-seq
one.
Update
Updated the code to take care of the case mentioned by ffriend in the comments.
Test:
user=> (print (apply str
(map-longest #(str %1 \space %2 \space %3 \newline) #(identity "--")
["a1" "a2" nil] ["b1" "b2"] ["c1" "c2" nil "c4"])))
a1 b1 c1
a2 b2 c2
-- -- --
-- -- c4
nil
Please note that this will replace nil
s in the colls with the value returned by the missing-value-fn
.