Clojure在指定位置从Vector中删除项目

Ham*_*aya 32 vector clojure

有没有办法从基于索引的向量中删除项目截至目前我正在使用subvec来拆分向量并再次重新创建它.我正在寻找向量的反向?

Bri*_*per 29

subvec可能是最好的方式.Clojure文档说的subvec是" O(1)并且非常快,因为结果向量与原始向量共享结构并且没有进行修剪 ".替代方案是走向量并构建一个新的向量,同时跳过某些元素,这将更慢.

从向量中间移除元素不是向量必然擅长的东西.如果您经常这样做,请考虑使用哈希映射,以便您可以使用dissoc.

看到:

  • subvec atclojuredocs.org
  • subvec at clojure.github.io,官方网站指向的地方.


zen*_*nna 21

(defn vec-remove
  "remove elem in coll"
  [coll pos]
  (vec (concat (subvec coll 0 pos) (subvec coll (inc pos)))))
Run Code Online (Sandbox Code Playgroud)


Tim*_*ley 15

user=> (def a [1 2 3 4 5])
user=> (time (dotimes [n 100000] (vec (concat (take 2 a) (drop 3 a)))))
"Elapsed time: 1185.539413 msecs"
user=> (time (dotimes [n 100000] (vec (concat (subvec a 0 2) (subvec a 3 5)))))
"Elapsed time: 760.072048 msecs"
Run Code Online (Sandbox Code Playgroud)

是的 - subvec是最快的


djh*_*987 7

矢量库clojure.core.rrb-vector提供对数时间串联和切片。假设您需要持久性,并考虑您的要求,对数时间解决方案在理论上尽可能快。特别是,它比使用 clojure 的 native 的任何解决方案快得多subvec,因为该concat步骤将任何此类解决方案放入线性时间。

(require '[clojure.core.rrb-vector :as fv])
(let [s (vec [0 1 2 3 4])]
  (fv/catvec (fv/subvec s 0 2) (fv/subvec s 3 5)))
; => [0 1 3 4]
Run Code Online (Sandbox Code Playgroud)


nar*_*isr 5

这是 iv 发现很好的解决方案:

(defn index-exclude [r ex] 
   "Take all indices execpted ex" 
    (filter #(not (ex %)) (range r))) 


(defn dissoc-idx [v & ds]
   (map v (index-exclude (count v) (into #{} ds))))

(dissoc-idx [1 2 3] 1 2)


'(1)
Run Code Online (Sandbox Code Playgroud)