2015-05-19 18 views
1

我有一個拉姆達加入C#,看起來像這樣:如何在F#中進行此加入?

int[] arrX = { 1, 2, 3 }; 
int[] arrY = { 3, 4, 5 }; 

var res = arrX.Join(arrY, x => x, y => y, (x, y) => x); 

執行RES後包含3這是兩個陣列常見。

我想在F#完全相同的拉姆達加入,並嘗試:

let arrX = [| 1; 2; 3 |] 
let arrY = [| 3; 4; 5 |] 

let res = arrX.Join(fun arrY, fun x -> x, fun y -> y, fun (x, y) -> x) 

但是編譯器說:

意外的象徵 '' 在lambda表達式。預期' - >'或其他令牌。

錯誤是第一個參數arrY後的逗號。

你能告訴我如何讓它工作(作爲lambda表達式)嗎?

+1

在你的身上ular實例,'System.Linq.Enumerable.Intersect(arrX,arrY)'不需要函數委託。 – kaefer

回答

3

這會爲我在F#-interactive工作(並且是從你的C#代碼直接翻譯):

執行 res
open System 
open System.Linq 

let arrX = [| 1; 2; 3 |] 
let arrY = [| 3; 4; 5 |] 

let res = arrX.Join(arrY, Func<_,_>(id), Func<_,_>(id), (fun x _ -> x)) 

看起來就像這樣:

> res;; 
val it : Collections.Generic.IEnumerable<int> = seq [3] 

言論

如果你喜歡,你可以寫

let res = arrX.Join(arrY, (fun x -> x), (fun x -> x), fun x _ -> x) 

作爲@RCH也提出了

+1

我想知道如果你喜歡 - 爲什麼不找''(fun x - > x)''比'Func <_, _>(id)' – CaringDev

+1

更可讀。我想這取決於你的口味 - 你甚至可以在arrX.Join(arrY,id,id,fun xy - > x)''let res = let id = Func <_,_>(fun x - > x)';) – Carsten

+0

Yes ,爲什麼不......我的F#口味還在不斷髮展,所以我歡迎每一個改進的機會:-) – CaringDev

1

請注意,至少有兩種方法可以使用F#core lib來執行此操作。

let arrX = [| 1; 2; 3 |] 
let arrY = [| 3; 4; 5 |] 

//method 1 (does not preserve order) 
let res1 = Set.intersect (set arrX) (set arrY) 

//method 2 
let res2 = 
    query { 
     for x in arrX do 
     join y in arrY on (x = y) 
     select x 
    } 
0

我可以大膽地建議如下:

open System 
open System.Linq 

let arrX = [| 1; 2; 3 |] 
let arrY = [| 3; 4; 5 |] 

let res = Set.intersect (Set.ofArray arrX) (Set.ofArray arrY) |> Set.toArray 

,或者去一些總的 「加密風格」:

let res' = arrX |> Set.ofArray |> Set.intersect <| (Set.ofArray <| arrY) |> Set.toArray 

我猜不建議res'版本。 ..

:-)