当我想要一个向量时,我经常发现自己使用了懒惰列表,反之亦然。此外,有时我有一个地图矢量,当我真的想要一组地图时。是否有任何辅助函数可以帮助我在这些类型之间进行转换?
答案 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"
into
是conj
的包装器,它是基于集合类型将新条目适当地插入集合的基本抽象。使这个流程变得如此美妙的原则是Clojure建立在可组合抽象之上,在这种情况下into
建立在集合顶部的conj
和seq
之上
如果收件人在运行时传入,上面的示例仍然会很好:因为底层抽象(seq
和conj
)是针对所有集合(以及许多Java集合)实现的因此,更高的抽象不需要担心许多与数据相关的特殊极端情况。
答案 1 :(得分:31)
vec
,set
和一般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}}