在Clojure中,有没有一种简单的方法可以在列表类型之间进行转换?


92

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

Answers:


144

别忘了,值得信赖的旧版into可以让您拿走所有seq能够填充的东西(列表,向量,地图,集合,排序地图)和要填充的空容器into

(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"

into是的包装conj,这是用于根据集合的类型将新条目适当地插入到集合中的基础抽象。使流程顺畅的原理是Clojure建立在可组合的抽象上,在这种情况下intoconj在collection和seq

如果在运行时传递接收者,上述示例仍然可以很好地构成:因为为所有集合(也包括许多Java的集合)实现了基础抽象(seqconj),因此不需要担心更高的抽象关于许多与数据相关的特殊情况


3
+1进入...值得注意的是,它也可以与非空原始容器一起使用(即,当您想添加到集合中时)
mikera 2011年

11
另外值得一提的是,由于into使用conj,这样做(into '() some-seq)将产生一个列表这就是反向一些-seq的,因为conjconses之外到列表。
Chuck

值得注意的是,into与大多数其他转换方式相比,利用瞬变(对于大多数seq类型)具有更好的性能特征。
Jarred Humphrey

现在,它可以与换能器一起使用,在撰写此答案时还不存在(我不知道瞬变是否也发生过)(这个答案已经足够老到可以上幼儿园了)
Arthur Ulfeldt 2016年

33

vecset并且通常into是您的朋友,可以轻松地将其“转换”为其他收藏集类型。

您想如何将地图矢量转换为地图地图?您需要一个键,可以提供示例输入/预期输出的使用吗?


抱歉,我是指一组地图。.我现在修改了问题
appshare.co

22

对于向量有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}}

4
当您进行非延迟调用lazy-seq而不是seq添加无用的间接调用时。如果真的要返回非零的东西,甚至没有空的收藏,那么那里的sequencelazy-seq有点低级的构造。
cgrand

14

从列表转换为地图的另一个答案(出于完整性考虑)-从这里开始

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

9

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

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

当您不想操纵数据时,只需seq在向量上使用:

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

相反的for,你可以只是做(map identity [1 2 3 4])
siltalau

7

无需向量转换为列表。当需要序列时,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}}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.