web-dev-qa-db-ja.com

Clojureは指定された場所にあるベクトルからアイテムを削除します

現在のインデックスに基づいてベクトルからアイテムを削除する方法は、サブベクシスを使用してベクトルを分割して再度再作成します。私はベクトルのアサコの逆を探していますか?

32
Hamza Yerlikaya

subvecはおそらく最善の方法です。 CLOJURE DOCSは、原稿と整備されていない構造が完了したベクトル共有構造が行われるため、subvecO(1)と非常に高速です」代替案はベクトルを歩き、特定の要素をスキップしながら新しいものを構築します。

ベクトルの真ん中からの要素を削除することは、ベクトルが必ずしも良いものではありません。これをしなければならない場合は、ハッシュマップを使用することを検討してください。dissocを使用できます。

見る:

29
Brian Carper
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"
 _

Yup - サブベッキは最速です

15
Timothy Pratley

これが素晴らしいことがわかった解決策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)
 _
4
narkisr

ベクトルライブラリ clojure.core.rrb-vector 対数の連結とスライスを提供します。あなたが持続的必要があると仮定し、あなたが求めているものを考えると、対数時間解は理論的には速く早くなります。特に、subvecステップはそのような解を線形時間にするので、Clojureのネイティブ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]
 _
3
djhaskin987