【问题标题】:Clojure - Why does into behave differently with a list than a vector?Clojure - 为什么 into 的行为与列表和向量不同?
【发布时间】:2013-12-01 16:43:39
【问题描述】:

当插入的集合不同时,为什么into 的行为会不同?例如:

user=> (into [] [1 2 3])
[1 2 3]

到目前为止,一切都很好。正如我所期望的那样。然而:

user=> (into () [1 2 3])
(3 2 1)

为什么这会颠倒论点?我假设它是为了性能,并且这些项目是按顺序插入的 cons?这似乎仍然打破了对我的抽象,在两个不同类型的有序集合中,我希望结果是一致的。

【问题讨论】:

    标签: clojure


    【解决方案1】:

    intoconjseq 在一起。

    conj 在开头添加列表,并在末尾添加向量以提高效率,因此无需遍历任一类型即可添加。

    Programming Clojure 在谈论 Clojure 中的 Collection 抽象时很好地解释了这一点:

    这些函数(conj/seq/count/empty/=)都是多态的 关于被操作的集合的具体类型。说过 另一种方式,每个操作都提供与 每个数据结构实现的约束。

    【讨论】:

      【解决方案2】:

      作为@MarkFisher 的answer 的附录:into 类似于reduce conjinto 的行为差异源于 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 的多态性。编写一个回文生成器,可以使用相同的函数来生成回文的头部和尾部,只需输入一个向量或一个列表。

      【讨论】:

        猜你喜欢
        • 2012-02-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-24
        • 1970-01-01
        • 2013-02-01
        • 2014-02-18
        • 2015-12-09
        相关资源
        最近更新 更多