Clojure地图最长 [英] Clojure map-longest

查看:119
本文介绍了Clojure地图最长的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想写一个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 
([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))))))))
pre>

测试:

  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 the missing-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 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 nils in the colls with the value returned by the missing-value-fn.

这篇关于Clojure地图最长的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆