次のような Clojure データ構造が必要です。
- 正面から飛び出す
- 後ろに押します
- インデックスを値に関連付けさせてください(つまり
(assoc q 0 1)
、フロントの値を1に設定します)
Clojure にそのようなものはありますか (残念ながら PersistentQueue は Nr.3 を満たしていません)、または vector の上に構築する必要がありますか?
次のような Clojure データ構造が必要です。
(assoc q 0 1)
、フロントの値を1に設定します)Clojure にそのようなものはありますか (残念ながら PersistentQueue は Nr.3 を満たしていません)、または vector の上に構築する必要がありますか?
標準のClojureには、これらの要件を効率的に満たすデータ構造はありません。
Clojure-Devメーリングリストで、ベクトルにRRBツリーを使用することについていくつかの話がありました。これは、このための優れたデータ構造になります。
それがどこまで発展したかはわかりませんが、この種のデータ構造に興味がある場合は、これを確認する価値があります。
データ構造の永続性が必要ない場合はjava.util.LinkedList
、Clojure プログラムで使用できます。
例:
;;; Creation
user> (import 'java.util.LinkedList)
java.util.LinkedList
user> (def linked-list (LinkedList. [:a :b :c :d :e]))
#'user/linked-list
;;; Pop from the front
user> (.pop ^LinkedList linked-list)
:a
user> linked-list
#<LinkedList [:b, :c, :d, :e]>
;;; Push to the rear, but costly
user> (.addLast ^LinkedList linked-list :x)
nil
user> linked-list
#<LinkedList [:b, :c, :d, :e, :x]>
;;; Assoc (cf. (assoc linked-list 0 :y)
user> (.add ^LinkedList linked-list 0 :y)
nil
user> linked-list
#<LinkedList [:y, :b, :c, :d, :x]>
pythonのdequestd::deque<T>
のようなdequeが必要なように聞こえますが、ドキュメントがややわかりにくいc++のインデックス付きアクセスパフォーマンス特性を好む場合があります。
Javaには、@ tnodaによるjava.util.LinkedListの提案のように、使用できるjava.util.Deque実装が付属しています。
独自にローリングしている場合、非永続コレクションの実装は非常に簡単であり、少なくともclojureのハッシュマップとベクトルの基礎となる「ハッシュ配列ツリー」に対して実装するか、詳細が最初にベクトルに対して直接実装することは、私にはかなり直感的に思えます。迷惑です。
sorted-mapを使用できますが、インデックス部分を自分で実装する必要があります。
たとえば、値 v をプッシュするには、マップ内の最後のキーをインクリメントして生成されたキーに関連付けることができます。ポップするには、マップの最初のキーを分離できます。