【问题标题】:Split a vector into vector of vectors in clojure instead of vector of lists将向量拆分为 clojure 中的向量向量而不是列表向量
【发布时间】:2014-02-18 01:24:55
【问题描述】:

split-at 的 clojure 文档声明它采用元素集合并返回两个 listsvector,每个包含大于或小于给定索引的元素:

(split-at 2 [1 2 3 4 5])
[(1 2) (3 4 5)]

我想要的是这个:

(split-at' 2 [1 2 3 4 5])
[[1 2] [3 4 5]]

这是一个集合分成两个集合,保持元素的顺序(如向量),最好没有性能损失。

执行此操作的常用方法是什么?是否有任何性能优化的方法来执行此操作?

【问题讨论】:

    标签: clojure


    【解决方案1】:

    为什么不用“vec”函数扩展核心函数呢?

    所以基于 split-at 定义:

    (defn split-at
      "Returns a vector of [(take n coll) (drop n coll)]"
      {:added "1.0"
       :static true}
      [n coll]
        [(take n coll) (drop n coll)])
    

    我们可以将vec添加到向量结果的每个元素中

    (defn split-at-vec
      [n coll]
        [(vec (take n coll)) (vec (drop n coll))])
    

    与“性能损失”有关,我认为当您将惰性序列转换为支持向量时,您就会失去惰性性能。

    【讨论】:

      【解决方案2】:

      如果您只使用矢量,一种选择是使用subvec

      (defn split-at' [idx v]
          [(subvec v 0 idx) (subvec v idx)])
      
      (split-at' 2 [1 2 3 4 5])
      ;; => [[1 2] [3 4 5]]
      

      关于性能,subvec state 上的文档:

      这个操作是 O(1) 并且非常快,因为 结果向量与原始向量共享结构,并且没有 修剪完成。

      【讨论】:

      • 需要修复空向量。哪个适用于split-at
      • @ClojureMostly 据我所知,它似乎适用于空向量:(= [[] []] (split-at' 0 []))
      • @ClojureMostly 啊,有道理;我认为这在技术上不是该函数的有效用法,但我想在某些情况下这种行为是有用的。
      • 我同意!最好保持简单。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多