当插入的集合不同时,为什么into
的行为会有所不同?例如:
user=> (into [] [1 2 3])
[1 2 3]
到目前为止,这么好。正如我所料。但是:
user=> (into () [1 2 3])
(3 2 1)
为什么这会颠倒争论?我假设它是为了性能,并且项目是按cons
顺序插入的?这似乎打破了我的抽象,在两个不同类型的有序集合中,我希望结果能够一致地排序。
答案 0 :(得分:7)
into
一起conj
和seq
。
conj在开头添加列表,并在结尾添加向量以提高效率,这样就不会遍历任何一种类型以便添加它。
在谈论Clojure中的Collection抽象时,Programming Clojure很好地解释了这一点:
这些函数(conj / seq / count / empty / =)都是多态的 关于正在进行的具体收集类型。说过 换句话说,每个操作都提供与语义一致的语义 每个数据结构实现的约束。
答案 1 :(得分:0)
作为@MarkFisher的answer的补遗:into
类似于reduce conj
; into
的行为差异来自conj
的行为差异:
(conj '(:b :c) :a) ;; '(:a :b :c) ;; prepend to lists
(conj [:a :b] :c) ;; [:a :b :c] ;; append to vectors
(conj #{:a :b} :c) ;; #{:a :b :c} ;; add to sets
(conj #{:a :b :c} :c) ;; #{:a :b :c} ;; nothing if already there
(conj {:a 1 :b 2} [:c 3]) ;; {:a 1 :b 2 :c 3} ;; add key-value
(conj {:a 1 :b 2 :c 3} [:c 4]) ;; {:a 1 :b 2 :c 4} ;; replace value if present
编辑:我最近使用了conj
的多态性。编写一个回文生成器,可以使用相同的函数生成回文的头部和尾部,只需通过喂食矢量或列表即可。