如何懒惰地迭代mapcat

时间:2016-12-12 23:03:01

标签: clojure

我想重复对输入执行mapcat操作。如,

(->> input
     (mapcat my-fn)
     (mapcat my-fn)
     (mapcat my-fn)
     (...))

有懒惰的方法吗?

我试过

(->> input
     (iterate #(mapcat my-fn %)))

但这并不是一个扁平的结构。

2 个答案:

答案 0 :(得分:2)

我做了一个人为的例子,我们想要反转一个数字列表,然后对它们进行一些数学计算以产生一个列表:

user> (def my-funs [reverse #(map inc %)])
#'user/my-funs

user> (reduce (fn [answer-so-far next-function]
                (mapcat next-function answer-so-far))
              [[[1 1 1] [2 2 2] [3 3 3]]
               [[2 2 2] [3 3 3] [4 4 4]]]
              my-funs)
(4 4 4 3 3 3 2 2 2 5 5 5 4 4 4 3 3 3)

reduce函数从列表的初始列表开始,然后将第一个函数应用于列表列表以产生到目前为止的答案,然后它接受第二个函数并将其应用于答案到目前为止产生下一个答案。如果您想到更多功能,可以根据需要多次继续。

我怀疑它不会让代码更具吸引力。

答案 1 :(得分:1)

flatten应该有效:

(->> input
     (iterate #(mapcat my-fn %))
     flatten)