2011-12-05 43 views
8

quiero comparar dos vectores y averiguar si los artículos que tienen son los mismos sin importar el orden de los artículos están en.comparar dos vectores en clojure sin importar el orden de los elementos

Así que ..

ahora mismo en clojure:

(= [1 2 3] [3 2 1]) ;=> false 

quiero:

(other_fun [1 2 3] [3 2 1]) ;=> true 

(other_fun [1 2 3 4] [3 2 1]) ;=> false 

no pude encontrar un containsA ll igual que en Java

Respuesta

12

Si no se preocupan por duplicados, puede crear conjuntos de ambos vectores y comparar estos:

(= (set [1 2 3]) (set [3 2 1])) ;=> true 

En función :

(defn set= [& vectors] (apply = (map set vectors))) 
4

crear conjuntos de ellos:

user=> (= (set [1 2 3]) (set [3 2 1])) 
true 


user=> (defn other_func [col1 col2] 
     (= (set col1) (set col2))) 
#'user/other_func 
user=> (other_func [1 2 3] [3 2 1]) 
true 
8

Si no le importan los duplicados, otras respuestas son perfectamente aplicables y eficientes. Pero si no se preocupan por duplicados, probablemente la forma más fácil de comparar dos vectores se ordenación y comparación:

user=> (= (sort [3 5 2 2]) (sort [2 2 5 3])) 
true 
user=> (= (sort [3 5 2 2]) (sort [2 5 3])) 
false 
21

Si haces atención sobre los duplicados, puede comparar sus mapas de frecuencia. Estos son mapas con cada elemento de colección como clave y cantidad de ocurrencias como valor. Puede crearlos utilizando la función estándar frequencies, como en los ejemplos dados.

orden diferente, el mismo número de duplicados:

(= (frequencies [1 1 2 3 4])(frequencies [4 1 1 2 3]))

evalúa true.

orden diferente, diferente número de duplicados:

(= (frequencies [1 1 2 3 4])(frequencies [4 1 2 3]))

evalúa false.

Por lo tanto, se puede escribir una función:

(defn other_fun [& colls] 
    (apply = (map frequencies colls))) 
2

Usted está en la JVM ya, así que si quieres containsAll, a continuación, sólo tiene que utilizar containsAll, ¿verdad?

+1

'containsAll' determina si una colección es un subconjunto de la otra colección. No determina la igualdad establecida. – Confusion

+0

@Confusion Puede usar 'a.containsAll (b) && b.containsAll (a)'. – bfontaine

1
(defn other_fun 
    "checkes the presence of the elements of vec1 in vec2 and vice versa" 
    [vec1 vec2] 
    (if (or (some nil? 
      (for [a vec1 b [vec2]] (some #(= % a) b))) 
     (some nil? 
      (for [a vec2 b [vec1]] (some #(= % a) b)))) 
    false 
    true)) 

(other_fun [1 2 3] [3 2 1]) ;=> true 

(other_fun [1 2 3 4] [3 2 1]) ;=> false 
+0

Puede simplificar '(si x falso verdadero)' como '(no x)'. – bfontaine

Cuestiones relacionadas