2011-12-05 20 views
8

我想比较两个向量,看看他们有项项都是一样的,不管订单的顺序。比较Clojure中的两个载体,不管项目

所以..

现在用Clojure:

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

我想:

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

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

我无法找到一个containsA LL像Java中

回答

12

如果你不关心重复,你可以创建两个向量组和比较这些:

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

作为一个功能:

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

从中创建集:

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

如果你不在乎重复,其他答案是完全适用和有效的。 但是,如果你关心的重复,可能比较两个向量的最简单方法是排序和比较:

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

如果做护理约重复,你可以比较它们的频率地图。这些映射与每个集合元素作为键和出现次数作为值。您可以使用标准功能frequencies创建它们,就像给出的例子。

顺序不同,相同数量的重复:

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

评估true

不同的顺序,不同数量的重复:

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

评估false

所以,你可以写一个函数:

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

你是在JVM上了,所以如果你想containsAll,那么就使用containsAll,对不对?

+1

'containsAll'确定一个集合是否是另一个集合的子集。它不确定集合的平等。 – Confusion

+0

@Confusion您可以使用'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

你可以简化'(如果x false true)'为'(not x)'。 – bfontaine