在Clojure中有一种简单的方法来转换列表类型?

时间:2011-02-23 09:00:48

标签: clojure

当我想要一个向量时,我经常发现自己使用了懒惰列表,反之亦然。此外,有时我有一个地图矢量,当我真的想要一组地图时。是否有任何辅助函数可以帮助我在这些类型之间进行转换?

6 个答案:

答案 0 :(得分:130)

让我们不要忘记,可信赖的旧into允许你带任何seq能够(列表,向量,地图,集合,有序地图)和一个你想要填充的空容器,并把它into 1}}它。

(into [] '(1 2 3 4)) ==> [1 2 3 4]         "have a lazy list and want a vector"
(into #{} [1 2 3 4]) ==> #{1 2 3 4}        "have a vector and want a set"
(into {} #{[1 2] [3 4]}) ==> {3 4, 1 2}    "have a set of vectors want a map"
(into #{} [{1 2} {3 4}]) ==> #{{1 2} {3 4}} "have a vector of maps want a set of maps"

intoconj的包装器,它是基于集合类型将新条目适当地插入集合的基本抽象。使这个流程变得如此美妙的原则是Clojure建立在可组合抽象之上,在这种情况下into建立在集合顶部的conjseq之上

如果收件人在运行时传入,上面的示例仍然会很好:因为底层抽象(seqconj)是针对所有集合(以及许多Java集合)实现的因此,更高的抽象不需要担心许多与数据相关的特殊极端情况。

答案 1 :(得分:31)

vecset和一般into是您的朋友,可轻松“转换”为其他收藏类型。

您想如何将地图矢量转换为地图地图?您需要一个密钥,是否可以使用样本输入/预期输出?

答案 2 :(得分:19)

对于向量,有vec函数

user=> (vec '(1 2 3))
[1 2 3]

对于延迟序列,有lazy-seq函数

user=> (lazy-seq [1 2 3])
(1 2 3)

为了转换成集合,有set函数

user=> (set [{:a :b, :c :d} {:a :b} {:a :b}])
#{{:a :b} {:a :b, :c :d}}

答案 3 :(得分:12)

从列表转换为地图(为了完整性)的另一个答案 - 来自here

(apply hash-map '(1 2 3 4))
;=>{1 2, 3 4}

答案 4 :(得分:8)

要将矢量转换为列表,您还可以使用for,如下所示:

=> (for [i [1 2 3 4]] i)
(1 2 3 4)

如果您不想操纵数据,只需在向量上使用seq

=> (seq [1 2 3])
(1 2 3)

答案 5 :(得分:6)

无需矢量转换为列表。当需要序列时,Clojure会处理一个向量,因为它会将列表视为一个序列。例如,

user=> (cons 0 [1 2 3])
(0 1 2 3)

如果您需要确保将矢量视为序列,请将其包装在seq中:

user=> (conj [1 2 3] 0) ; treated as a vector
[1 2 3 0]

user=> (conj (seq [1 2 3]) 0) ; treated as a sequence
(0 1 2 3)

如果你有一个地图矢量,并且你想要一组地图,那么矢量保存地图并不重要。您可以像往常一样将矢量转换为集合:

user=> (set [{:a 1, :b 2} {"three" 3, "four" 4}])
#{{:a 1, :b 2} {"four" 4, "three" 3}}