Clojureでは、リストでベクターを使用する必要があるのはいつですか?


回答:


112

繰り返しますが、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

フリーノードにいる間、ダークサイドに来て#stackoverflowに参加しましょう!:-P
クリスジェスター-ヤング

私は実際にそこで遊んでいました。IRCクライアントを切り替えましたが、自動参加リストに#stackoverflowを追加することは考えていませんでした。
レイン、

私はLispの初心者ですが、ベクトル、マップ、およびセットが、すべてのコードがデータと交換可能であるという考えに何らかの影響があるかどうか疑問に思いましたか?それとも、これはClojureを実用的なLispにするものの1つにすぎませんか?(または、ベクトルを評価できますか?)
ロブ・グラント

23
これはまったく役に立たないチャットスニペットです。「コードを生成する」「バックトゥフロントを生成する」->正確に意味しますか?私の本では、怠惰+宣言型スタイル=はるかに優れたパフォーマンスなので、この質問に本当に苦労しています。
ジミーホファ2014

22
@JimmyHoffa私が理解する方法: "Generating Code" = "Inside a Macro"(ほとんどのコードは関数呼び出しなので、リストなので); 「前から後ろへの生成」=「先頭に追加してシーケンスを構築する」。
omiel 14

87

Javaプログラミングの経験が多く、Javaコレクションフレームワークに精通している場合は、のようなリストLinkedListやのようなベクトルを考えてArrayListください。したがって、ほとんど同じ方法でコンテナを選択できます。

さらに明確にするために、アイテムをシーケンスの前または後ろに個別にたくさん追加するつもりである場合、アイテムは毎回シャッフルする必要がないので、リンクリストはベクトルよりもはるかに優れています。ただし、特定の要素(リストの前後ではない)に頻繁にアクセスする場合(つまり、ランダムアクセス)、ベクターを使用する必要があります。

ちなみに、ベクトルは簡単にシーケンスに変換できます。

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)

ベクトルはシーケンスではありませんが、シーケンシャルです。(情報源:freenodeの#clojureでRich自身。)また、私はJavaをまったく知りませんが、Richは私の質問に答えました。
レイン、

1
私の投稿を編集して、ベクトルはseq関数を使用してseqにすることができます。:-)
クリスジェスター-ヤング

2
それは確かに質問に答えたのであなたの答えを選んだ、そして私は自分の答えを正しいものとして選ぶのは本当に好きではない。正しくないようです。ありがとう。:)
レイン2007

最初と最後を追加する場合、両端キューはリンクリストよりも優れています。LLはかなりひどい:P
ボックス化

1
@boxedベクトルの上に両端キューを実装したりArrayList、効果的にArrayDeque自分自身を再実装しないと、両端キューを実装できません。
Chris Jester-Young、

43

ベクトルにはO(1)のランダムアクセス時間がありますが、事前に割り当てる必要があります。リストは動的に拡張できますが、ランダム要素へのアクセスはO(n)です。


3
技術的には、リンクリストにはO(1)アクセス時間があります...前面または背面の要素のみにアクセスしている場合。:-Pただし、ベクトルにはO(1)のランダムアクセスがあります。:-)
Chris Jester-Young

4
(上記の「リンクされたリスト」は、二重にリンクされたリストを指します。単一にリンクされたリストには、フロントエレメントへのO(1)アクセスのみがあります。:
Chris Jester-Young

1
誰かがClojureに飛び込むだけなので、これは他の2票より投票数が多い方法よりも優れた答えです。他の2つは何の役にも立たない。
keithjgrant 2014年

@ ChrisJester-Young単一リンクリストは、そのように back要素への参照を格納している場合、O(1)アクセスをサポートできます。
ギルベイツ

30

ベクトルを使用する場合:

  • インデックスアクセスのパフォーマンス-リストのO(n)に対して、インデックスアクセスのコストは〜O(1)になります。
  • 追加-conjは〜O(1)
  • 便利な表記法-どちらでも機能する状況で、リテラルリストの場合、「(1 2 3)」よりも入力と[1 2 3]の両方を読む方が簡単だと思います。

リストを使用する場合:

  • シーケンスとしてアクセスしたい場合(リストは新しいオブジェクトを割り当てる必要なしにseqを直接サポートするため)
  • 先頭に追加-consまたはできればconjを含むリストの先頭に追加するとO(1)

3
両端で追加/削除する場合でも、リストはかなりひどい選択です。両端キューははるかに優れています(CPU、特にメモリにおいて)。github.com/pjstadig/deque-clojureをお
ボックス化

2
Re:~O(1)このコストの説明が役立つかもしれない人のために-stackoverflow.com/questions/200384/constant-amortized-time
Merlyn Morgan-Graham

13

簡単な補足説明:

「ベクターはシーケンスではないが、リストはシーケンスだと読んだ。」 

シーケンスは、リストまたはベクトル(またはマップまたはセット)よりも一般的です。REPLがリストとシーケンスを同じように出力するのは
残念ですが、リストが異なっていてもリストはシーケンスのように見えます。(seq)関数は、リストを含むさまざまなものからシーケンスを作成し、そのseqを、seqsで気の利いたことを実行する多数の関数にフィードできます。

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には、すでにシーケンスである場合に引数を返すショートカットがあります。

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);
}

リストはシーケンスですが、他のものも同様であり、すべてのシーケンスがリストであるとは限りません。


私は小さな点を選ぶつもりはありません、それは便利なものを指摘するための単なる機会です。多くの人はすでにこれを知っています:)
アーサー・

2
あなたが意味するものではありません。class代わりにclass?
qerub 2012

clojureの更新後に例が変更されたかどうかはわかりませんが(私は1.5を使用していると思います)、どちらの例も返さclojure.lang.PersistentListれます。私はあなたが書かclassないつもりだったと思いますclass?
Adrian Mouat 2013年

確かに!私はそれを修正します
Arthur Ulfeldt 2013年

まだ少し混乱しています。classあなたが言及したこれらの式の両方に対して同じPersistentListを返すので、これはシーケンスとリストが実際にまったく同じものであることを意味しますか?
johnbakers、2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.