2011-12-05 18 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