代码之家  ›  专栏  ›  技术社区  ›  Rayne

在Clojure中,什么时候应该在列表上使用向量,而在另一方面呢?

  •  136
  • Rayne  · 技术社区  · 15 年前

    我读到向量不是SEQ,但列表是。我不知道用一个比另一个的理由是什么。看来矢量是最常用的,但有什么原因吗?

    5 回复  |  直到 7 年前
        1
  •  104
  •   Rayne    15 年前

    再一次,我似乎已经回答了我自己的问题,变得不耐烦,并在Freenode的Clojure中提问。在stackoverflow.com上鼓励回答自己的问题:d

    我和里奇·希基进行了一次简短的讨论,主要内容如下。

    [12:21] <Raynes>    Vectors aren't seqs, right?
    [12:21] <rhickey>   Raynes: no, but they are sequential
    [12:21] <rhickey>   ,(sequential? [1 2 3])
    [12:21] <clojurebot>    true
    [12:22] <Raynes>    When would you want to use a list over a vector?
    [12:22] <rhickey>   when generating code, when generating back-to-front
    [12:23] <rhickey>   not too often in Clojure
    
        2
  •  80
  •   C. K. Young    15 年前

    如果您已经做了很多Java编程,并且熟悉Java集合框架,请考虑类似的列表。 LinkedList 和向量 ArrayList . 所以你可以用同样的方法选择容器。

    更进一步的说明:如果你想在序列的前面或后面单独添加项目,一个链接列表比一个向量要好得多,因为这些项目不需要每次都随机排列。但是,如果您希望经常访问特定的元素(不在列表的前面或后面),即随机访问,那么您将希望使用vector。

    顺便说一下,向量可以很容易地转化为seq。

    user=> (def v (vector 1 2 3))
    #'user/v
    user=> v
    [1 2 3]
    user=> (seq v)
    (1 2 3)
    user=> (rseq v)
    (3 2 1)
    
        3
  •  36
  •   Svante    15 年前

    向量有O(1)个随机访问时间,但它们必须预先分配。列表可以动态扩展,但是访问一个随机元素是O(N)。

        4
  •  28
  •   Thumbnail    10 年前

    何时使用矢量:

    • 索引访问性能-索引访问的开销为~o(1),而列表的开销为o(n)
    • 附加-with conj为~o(1)
    • 方便的符号-我发现在任何一个都可以工作的情况下,输入和读取[1 2 3]都比(1 2 3)更容易。

    何时使用列表:

    • 当您想按顺序访问它时(因为列表直接支持seq而不需要分配新对象)
    • 前置-在列表的开头加上cons,或者最好是conj是o(1)
        5
  •  13
  •   Arthur Ulfeldt    11 年前

    只是一个简短的旁注:

    "I read that Vectors are not seqs, but Lists are." 

    序列比列表或向量(或映射或集合)更通用。
    不幸的是 repl打印相同的列表和序列 因为它确实让列表看起来像是序列,即使它们是不同的。(seq)函数将从许多不同的东西(包括列表)中生成一个序列,然后您可以将该seq输入到使用seq做漂亮事情的函数的任何一个过多的函数中。

    user> (class (list 1 2 3))
    clojure.lang.PersistentList
    
    user> (class (seq (list 1 2 3)))
    clojure.lang.PersistentList
    
    user> (class (seq [1 2 3]))
    clojure.lang.PersistentVector$ChunkedSeq
    

    sec有一个快捷方式,如果它已经是seq,则返回其参数:

    user> (let [alist (list 1 2 3)] (identical? alist (seq alist)))
    true
    user> (identical? (list 1 2 3) (seq (list 1 2 3)))
    false
    
    static public ISeq seq(Object coll){
            if(coll instanceof ASeq)
                    return (ASeq) coll;
            else if(coll instanceof LazySeq)
                    return ((LazySeq) coll).seq();
            else
                    return seqFrom(coll);
    }
    

    列表是序列,但其他东西也是,并非所有的序列都是列表。