2009-10-02 29 views

Respuesta

5
user=> (use 'clojure.set) 
nil 
user=> (difference (set [1 2 3 4 5]) (set [2 3 5])) 
#{1 4} 

Referencia:

+0

¿Hay algún problema con esta solución? –

+2

Un vector no es un conjunto. El orden del vector no se conserva cuando lo convierte a un conjunto. Si entiendo la pregunta correctamente, (diferencia [set [9 2 3 4 5]) (set [2 3 5])) devuelve # {4 9} cuando debería devolver [9 4] y (diferencia (set [1 1 2 3 4 5]) (set [2 3 5])) debería devolver [1 1 4] y no # {1 4} Si quisiera establecer la semántica, probablemente habría usado un conjunto para empezar con. – Jonas

+0

Gracias, Jonas. Probablemente tengas razón acerca de que él no quiere establecer la semántica. –

17

Prueba esto:

(let [a [1 2 3 4 5] 
     b [2 3 5]] 
    (remove (set b) a)) 

que devuelve (1 4).

La función remove, por cierto, toma un predicado y una colección, y devuelve una secuencia de los elementos que no satisfacen el predicado (un conjunto, en este ejemplo).

+1

... que es O (n + m) – Thumbnail

+0

¿cómo funciona '(set)' aquí como un predicado para 'remove'? ¿Alguien puede explicarlo? No necesita el predicado para devolver falso para algunos elementos en coll? – amirteymuri

+0

Un conjunto también es una función que devolverá el valor que se le da si ese valor es en sí mismo, o nulo si no lo es. Si usa esta función como un predicado, el valor devuelto se convierte en verdadero, o nil devuelto se convierte en falso. Esto es porque en Clojure nil es 'falsey'. –

1

Puede hacerlo usted mismo con algo como:

(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) 

Una versión basada en la biblioteca reducers podría ser:

(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] 

EDITAR-ss contiene Agregado? código

+2

Hola, Nicolas, me puede estar faltando un punto, ¿pero contiene AFAIK? realmente no verifica el "contenido", sino que verifica el índice; consulte este ejemplo; (contiene? [7 2 3 4 5 6] 6);; falso, no hay elemento en el índice 6, aunque hay un elemento 6. –

+0

Gracias por el puntero. Lo olvidé totalmente. Agregó el código para un seq-contiene? función. –

0

Aquí está mi toma sin usar conjuntos;

(defn my-diff-func [X Y] 
    (reduce #(remove (fn [x] (= x %2)) %1) X Y)) 
Cuestiones relacionadas