在Clojure中将'map'与不同大小的集合一起使用 [英] Using 'map' with different sized collections in clojure

查看:138
本文介绍了在Clojure中将'map'与不同大小的集合一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想了解在Clojure中处理不同大小的集合的惯用方式.有什么办法可以让函数'map'用默认值填充集合的其余部分?

作为一个例子,假设我有3个向量:

(def x [1 2 3 4])
(def y [1 2 3 4 5])
(def z [1 2 3 4 5 6 7])

(map + x y z)    ; yields (3 6 9 12)

在这种情况下,我如何用零填充x和y并产生这样的收益:

(3 6 9 12 10 6 7)

解决方案

map本身并不做,但是您可以结合使用concatrepeat来获得所需的结果:

(def x [1 2 3 4])
(def y [1 2 3 4 5])
(def z [1 2 3 4 5 6 7])

(map +
     (concat x (repeat 0))
     (concat y (repeat 0))
     z) ; => (3 6 9 12 10 6 7)

这是 concat ,并针对重复.

这是一个草图,您可以将其抽象一些,因此您无需知道哪个集合最长. (在上面的代码段中,如果将concat的所有集合concat concat,则将有一个无限的序列).

(defn map-longest
  [f default & colls]
  (lazy-seq
   (when (some seq colls)
     (cons
      (apply f (map #(if (seq %) (first %) default) colls))
      (apply map-longest f default (map rest colls))))))

(map-longest +
             0
             [1 2 3 4]
             [1 2 3 4 5]
             [1 2 3 4 5 6 7]) ; => (3 6 9 12 10 6 7)

您可以看到其他几种方法来作为之前有关堆栈溢出的问题的答案.

>

I'd like to understand the idiomatic way with which to operate over collections of different sizes in clojure. Is there a way I can tell the function 'map' to pad the rest of a collection with some default value?

As an example, suppose I have 3 vectors:

(def x [1 2 3 4])
(def y [1 2 3 4 5])
(def z [1 2 3 4 5 6 7])

(map + x y z)    ; yields (3 6 9 12)

In this case, how can I pad x and y with zeroes and have this yield:

(3 6 9 12 10 6 7)

解决方案

map doesn't do it itself, but you can use a combination of concat and repeat to obtain the desired result:

(def x [1 2 3 4])
(def y [1 2 3 4 5])
(def z [1 2 3 4 5 6 7])

(map +
     (concat x (repeat 0))
     (concat y (repeat 0))
     z) ; => (3 6 9 12 10 6 7)

Here's the API documentation for concat, and for repeat.

And here's a sketch of how you could abstract this away a bit, so you don't need to know which of the collections is longest. (In the snippet above, if you concat all the collections to (repeat 0) you'll have an infinite sequence).

(defn map-longest
  [f default & colls]
  (lazy-seq
   (when (some seq colls)
     (cons
      (apply f (map #(if (seq %) (first %) default) colls))
      (apply map-longest f default (map rest colls))))))

(map-longest +
             0
             [1 2 3 4]
             [1 2 3 4 5]
             [1 2 3 4 5 6 7]) ; => (3 6 9 12 10 6 7)

You can see a couple other approaches as answers to this previous question on Stack Overflow.

这篇关于在Clojure中将'map'与不同大小的集合一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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