Clojure地图最长

Ral*_*lph 5 clojure map

我正在尝试编写一个名为Clojure的实用程序函数map-longest(备用名称建议赞赏).此功能将具有以下"签名":

(map-longest fun missing-value-seq c1 & colls)
Run Code Online (Sandbox Code Playgroud)

并且将表现得类似map,除了它将继续处理提供的集合,直到最长的用尽.对于短于最长的集合,当它用完了值时,它将从中获取它们missing-values-seq.它应该是懒惰的,但显然不能与无限集合一起使用.

使用示例:

(print (apply str
  (map-longest #(str %1 \space %2 \space %3 \newline) (repeatedly "--")
    ["a1" "a2" "a3"] ["b1" "b2"] ["c1" "c2" "c3" "c4"])))
Run Code Online (Sandbox Code Playgroud)

应该产生以下输出:

a1 b1 c1
a2 b2 c2
a3 -- c3
-- -- c4
Run Code Online (Sandbox Code Playgroud)

但我可能有错误的电话.

我该如何实现?clojure.core或clojure-contrib库是否已经有类似的东西?作为替代方案missing-value-seq,传递第二个函数来生成缺失值会更好#(identity "--")吗(例如:在我的例子中)?

使用案例:我正在编写一个小文本蜘蛛纸牌播放器作为学习Clojure /函数式编程的练习.我需要能够显示游戏tableaus(纯粹主义者的表格:-)).

Abh*_*kar 5

这是一个解决方案:

(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))))))))
Run Code Online (Sandbox Code Playgroud)

测试:

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
Run Code Online (Sandbox Code Playgroud)

请注意,我采用了这种missing-value-fn方法而不是missing-value-seq一种方法。

更新

更新了代码以处理 ffriend 在评论中提到的案例。

测试:

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
Run Code Online (Sandbox Code Playgroud)

请注意,这会将nilcolls 中的 s替换为missing-value-fn.