J'ai une liste [2 3 5] que je veux utiliser pour supprimer des éléments d'une autre liste comme [1 2 3 4 5], de façon à obtenir [1 4].Comment supprimer plusieurs éléments d'une liste?
grâce
J'ai une liste [2 3 5] que je veux utiliser pour supprimer des éléments d'une autre liste comme [1 2 3 4 5], de façon à obtenir [1 4].Comment supprimer plusieurs éléments d'une liste?
grâce
user=> (use 'clojure.set)
nil
user=> (difference (set [1 2 3 4 5]) (set [2 3 5]))
#{1 4}
Référence:
Y at-il un problème avec cette solution? –
Un vecteur n'est pas un ensemble. L'ordre du vecteur n'est pas conservé lorsque vous le convertissez en ensemble. Si je comprends bien la question, (différence (set [9 2 3 4 5]) (set [2 3 5])) renvoie # {4 9} quand il devrait retourner [9 4] et (différence (set [1 1 2 3 4 5]) (set [2 3 5])) devrait retourner [1 1 4] et pas # {1 4} S'il voulait définir la sémantique, il aurait probablement utilisé un ensemble pour commencer avec. – Jonas
Merci, Jonas. Tu as probablement raison de dire qu'il ne veut pas de sémantique. –
Essayez ceci:
(let [a [1 2 3 4 5]
b [2 3 5]]
(remove (set b) a))
qui renvoie (1 4)
. Soit dit en passant, la fonction remove
prend un prédicat et une collection, et renvoie une séquence d'éléments qui ne satisfont pas le prédicat (un ensemble, dans cet exemple).
... qui est O (n + m) – Thumbnail
Comment '(set)' fonctionne-t-il ici en tant que prédicat pour 'remove'? Quelqu'un peut-il l'expliquer? Vous n'avez pas besoin du prédicat pour renvoyer false pour certains éléments de coll? – amirteymuri
Un ensemble est aussi une fonction qui retournera la valeur qui lui est donnée si cette valeur est en elle-même, ou nil si ce n'est pas le cas. Si vous utilisez cette fonction en tant que prédicat, la valeur renvoyée devient true ou nil retournée devient false. C'est parce que dans Clojure nil est «falsey». –
Vous pouvez faire vous-même avec quelque chose comme:
(def a [2 3 5])
(def b [1 2 3 4 5])
(defn seq-contains?
[coll target] (some #(= target %) coll))
(filter #(not (seq-contains? a %)) b)
; (3 4 5)
Une version basée sur la bibliothèque reducers pourrait être:
(require '[clojure.core.reducers :as r])
(defn seq-contains?
[coll target]
(some #(= target %) coll))
(defn my-remove
"remove values from seq b that are present in seq a"
[a b]
(into [] (r/filter #(not (seq-contains? b %)) a)))
(my-remove [1 2 3 4 5] [2 3 5])
; [1 4]
EDITAjouté seq-contient? code
Salut Nicolas, il se peut que je manque un point mais AFAIK contient? ne vérifie pas vraiment "contenu" mais vérifie plutôt l'index, consultez cet exemple; (contient? [7 2 3 4 5 6] 6) ;; false, il n'y a pas d'élément à l'index 6, bien qu'il y ait un élément 6. –
Merci pour le pointeur. J'ai complètement oublié. Ajout du code pour un seq-contains? fonction. –
Voici ma prise sans utiliser de jeux;
(defn my-diff-func [X Y]
(reduce #(remove (fn [x] (= x %2)) %1) X Y))
[] indique que le vecteur n'est pas une liste – Roskoto