Clojure地图最长 [英] Clojure map-longest
问题描述
我想写一个Clojure效用函数 map-longest
(备用名称建议赞赏)。此函数将具有以下签名:
(map-longest fun missing-value-seq c1& colls)
,其行为类似于 map
它将继续处理提供的集合,直到最长用尽。对于短于最长的集合,当它的值不足时,它将从 missing-values-seq
中获取它们。它应该是惰性的,但显然不能用于无限集合。
使用示例:
(print(apply str
(map-longest#(str%1 \space%2 \space%3 \ newline)(重复 - )
[ a1a2a3] [b1b2] [c1c2c3c4]))
应生成以下输出:
a1 b1 c1
a2 b2 c2
a3 - c3
- - c4
但我可能调用错误。
如何实现? clojure.core或clojure-contrib库已经有这样的东西吗?作为 missing-value-seq
的替代方法,最好传入第二个函数来生成缺失值(例如:# - )
在我的例子中)?
用例:我写一个小文本蜘蛛纸牌玩家作为一个练习在Clojure /功能编程。
这里是一个解决方案:
/ p>(defn map-longest
pre>
([fn missing-value-fn c1]
(map fn c1 ))
([fn missing-value-fn c1& colls]
(lazy-seq
(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))))))))
测试:
user => (print(apply str
(map-longest#(str%1 \space%2 \space%3 \\\
ewline)#(identity - )
[a1a2 a3] [b1b2] [c1c2c3c4]))
a1 b1 c1
a2 b2 c2
a3 - - c3
- - c4
nil
请注意,
missing-value-fn
方法,而不是missing-value-seq
方法。
更新
更新了代码,以处理ffriend在评论中提到的情况。
测试:
user => (print(apply str
(map-longest#(str%1 \space%2 \space%3 \\\
ewline)#(identity - )
[a1a2 nil] [b1b2] [c1c2nilc4]))
a1 b1 c1
a2 b2 c2
-
- - c4
nil
请注意, code> nil 与
missing-value-fn
所返回的值相同。I am trying to write a Clojure utility function called
map-longest
(alternate name suggestion appreciated). This function will have the following "signature":(map-longest fun missing-value-seq c1 & colls)
and will behave similarly to
map
, except than it will continue processing the supplied collections until the longest is exhausted. For collections shorter than the longest, when it runs out of values, it will take them from themissing-values-seq
. It should be lazy, but obviously cannot be used with infinite collections.Example use:
(print (apply str (map-longest #(str %1 \space %2 \space %3 \newline) (repeatedly "--") ["a1" "a2" "a3"] ["b1" "b2"] ["c1" "c2" "c3" "c4"])))
It should produce the following output:
a1 b1 c1 a2 b2 c2 a3 -- c3 -- -- c4
but I may have the call wrong.
How do I implement this? Does the clojure.core or clojure-contrib library already have something like this? As an alternative to
missing-value-seq
, would it be better to pass in a second function to generate the missing values (e.g.:#(identity "--")
in my example)?Use case: I am writing a small text spider solitaire player as an exercise in learning Clojure/functional programming. I need to be able to display the game tableaus (tableaux for purists :-)).
解决方案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 themissing-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 themissing-value-fn
.这篇关于Clojure地图最长的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!