获得自然的 clojure conj 顺序

Get natural clojure conj order

(conj coll x),出于性能原因,会将 x 添加到某些集合的末尾和其他集合的开头。

有没有办法检查集合是自然地在末尾添加还是在开始添加?即

(conj-at-end? x) ; false for lists and true for vectors.

通过检查某项是向量还是列表等,我自己编写相当容易,但是如果添加了新集合或更改了某些内容,这很容易出错。

conjIPersistentCollection interface 的一部分。该接口只定义了三个方法:

  • conj - 添加新元素;
  • empty - returns一个相同类型的空集合;
  • equiv - 执行相等性检查。

所以,没有什么比 conj-at-end?.

我也不认为它可以实现。例如,您将如何为 hash-maps and hash-sets?

等内部未排序的集合定义它
(conj #{1 2 3 4 5} 6)
; => #{1 4 6 3 2 5}

conj 添加到集合的开头还是结尾?

这个问题只对顺序集合有意义,你可以试试:

定义

(defn conj-at-end? [coll]
  (and (sequential? coll)
       (= (conj (empty coll) 1 2) [1 2])))

然后

(conj-at-end? []) ;=> true
(conj-at-end? ()) ;=> false

(conj-at-end? #{}) ;=> false

我们还需要相应的

(defn conj-at-beginning? [coll]
  (and (sequential? coll)
       (= (conj (empty coll) 1 2) [2 1])))

然后

(conj-at-beginning? []) ;=> false
(conj-at-beginning? ()) ;=> true

(conj-at-beginning? #{}) ;=> false

请注意,集合既不是 conj-at-beginning? 也不是 conj-at-end?


如果 clojure.lang.PersistentArrayMaps 由 array-map

生成,那么这个相当 pat 的解决方案将会被打乱
  • conj 下稳定,但他们不是,
  • 选符合空clojure.lang.Sequential界面, 由 sequential? 测试,但他们没有。