2015-02-23 125 views
3

我有兩個數組,我想從第二個數組中找不到第一個數組中的元素。查找FSharp中兩個數組之間的差異

我寫了下面的代碼:

let array0 = [|"A";"B";"C"|] 
let array1 = [|"B";"D";"E"|] 

let inZero letter = 
    array0 |> Array.tryFind(fun l -> if l = letter then true else false) 

array1|> Array.filter(fun l -> inZero(l).IsSome) 

但我不知道是否有東西是更地道到FSharp。

在此先感謝

+0

除此之外,現在刪除的建議使用'Enumerable.Except'的答案聽起來也是一個不錯的選擇。 – 2015-02-23 20:05:49

+1

如果你準備等到F#4.0(或者可能是4.1),那麼有一個對Array.Except打開的拉取請求:) https://github.com/Microsoft/visualfsharp/pull/253 – 2015-02-23 20:13:32

回答

4

如果你不關心重複,那麼你可以寫這個使用F#集:

// Elements that are in array1, but not in array0 
set array1 - set array0 

// Elements that are in both arrays (which is what your sample returns) 
Set.intersect (set array1) (set array0) 

在這兩種情況下,你得到一個新的set<int>,這也是seq<int>,所以你可以迭代它或使用Array.ofSeq將它變回數組。

如果您想保留重複項(如果array1中有重複項,則多次返回該元素),那麼我認爲您擁有的是好的。如果你想對一個比較多個陣列,那麼它會是有意義的轉array0到字典中更有效地查找:

let inZero = 
    let set0 = set array0 
    set0.Contains 

// Elements from array1 that are also in array0 (returns multiple 
// copies of the same element if it appears repeatedly in array1) 
array1 |> Array.filter inZero 

要設置的轉換有一定的成本,但它減少了查找時間。所以,根據你如何使用這個陣列的大小,這將具有不同的性能特徵。但代碼看起來更好,所以這將是我的默認選擇。

+0

我的意思是做.IsNone so返回兩者都不是。做一個不Set.intersect? – 2015-02-23 20:00:56

+0

設置的差異('set array1 - set array0')應該給你'array1'中的元素,但不是'array0'中的元素(交集做你的代碼與'IsSome'做的事情) – 2015-02-23 20:03:51

相關問題