2015-02-23 74 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

相关问题