web-dev-qa-db-ja.com

Clojureでシーケンスからアイテムを削除するにはどうすればよいですか?

最初に、各構造固有のシーケンスがアイテムを削除するさまざまな方法を持っていると想定します:Vectorsはインデックスによって、Listは最初または最後に削除できます。Setは、削除する実際のアイテムを渡す必要があります。

第二に、構造にとらわれない除去方法がいくつかあると思います。 seqインターフェースで動作します。

Clojureではシーケンスは不変であるため、実際に行っているのは、オリジナルのアイテムなしで、オリジナルの安価なコピーを作成しているのではないかと思います。これは、リスト内包表記が削除に使用できることを意味しますが、不必要に冗長になると思います。

Clojureシーケンスからアイテムを削除するさまざまな方法の慣用的な例をいくつか挙げてください。

34
Robert Campbell

おそらくパフォーマンス特性が異なるため、Clojureのすべてのデータ構造型から削除するための単一のインターフェイスはありません。

(disj #{:foo :bar} :foo)       ; => #{:bar}
(dissoc {:foo 1 :bar 2} :foo)  ; => {:bar 2}
(pop [:bar :foo])              ; => [:bar]
(pop (list :foo :bar))         ; => (:bar)

これらも機能します(seqを返す):

(remove #{:foo} #{:foo :bar})      ; => (:bar)
(remove #{:foo} [:foo :bar])       ; => (:bar)
(remove #{:foo} (list :foo :bar))  ; => (:bar)

これはハッシュマップでは機能しません。マップを反復処理すると、キーと値のペアが取得されるためです。しかし、これはうまくいきます:

(remove (fn [[k v]] (#{:foo} k)) {:foo 1 :bar 2})  ; => ([:bar 2])
43
Brian Carper

Clojureシーケンスのリファレンス を見てください。 filterremoveが求めているものです。

12
Svante

ブライアン・カーパーの答えの延長として。結果によって何をするかによります。データセット全体で作業する(つまり、印刷する)必要があるものに結果を渡す場合シーケンスを作成し、フィルターを使用するか削除して問題を遅延して解決するのは慣用的です。一方、後で使用するために保存するようにデータ構造を変更している場合は、その上にシーケンスを作成すると、適切な更新特性が失われるため、この場合、そのデータ構造に固有の更新関数を使用する方が適切です。

2
Arthur Ulfeldt