Как удалить элемент из последовательности в Clojure?

во-первых, я предполагаю, что каждая структурная последовательность будет иметь разные способы удаления элемента:векторы может быть по индексу,список можно удалить первым или последним, Set должен проходить фактический элемент для удаления и т. д.

во-вторых, я предполагаю, что есть некоторые методы удаления, которые являются структурными агностиками; они работают на seq интерфейс.

поскольку последовательности неизменяемы в Clojure, я подозреваю, что вы на самом деле делать это делать дешевую копию оригинала, только без оригинального элемента. Это означает, что понимание списка может быть использовано для удаления, но я подозреваю, что это будет излишне многословно.

пожалуйста, приведите некоторые идиоматические примеры различных способов удаления элементов из последовательностей Clojure.

3 ответов


нет единого интерфейса для удаления вещей из всех типов структуры данных 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])

посмотреть ссылка Clojure для последовательностей. filter и remove это то, что вы ищете.


как продолжение ответа Брайана Карпера. Это зависит от того, что вы будете делать с результатом. Если вы передаете результат чему-то, что хочет работать со всем набором данных (т. е. печатать его), идиоматично сделать seq и использовать фильтр или удалить, чтобы лениво решить проблему. Если, с другой стороны, вы изменяете структуру данных для сохранения для различных более поздних применений, то создание seq на нем потеряет свои благоприятные характеристики обновления, поэтому в этом случае лучше использовать функция обновления, специфичная для этой структуры данных.