2009-12-19 44 views
1

我有一個記錄列表在F#lambda表達式返回不同類型的數組

type Item = { Color : string; Size : int} 
let itemList = [{Color="Red"; Size=1}; 
       {Color="Green"; Size=2}; 
       {Color="Blue"; Size=3};] 

我希望得到把我的記錄列表到值的數組一樣 [|「紅」; 「綠」, 「藍」 |]或[| 1; 2; 3 |]

我可以八九不離十那裏像這樣

type ItemType = 
| Color of string 
| Size of int 

type ItemEnum = 
| C 
| S 

let GetProp x y = 
match x with 
| C -> List.toArray y |> Array.map(fun x -> ItemType.Color(x.Color)) 
| S -> List.toArray y |> Array.map(fun x -> ItemType.Size(x.Size)) 

,但是當我打電話GetProp S itemList我回來[|大小1;大小2;大小3 |]。有用但不完全是我要找的。

我已經試過以下

let GetProp2 x y : 'a[] = 
match x with 
| Color -> List.toArray y |> Array.map(fun x -> x.Color) 
| Size -> List.toArray y |> Array.map(fun x -> x.Size) 

,但它並不像兩個不同的返回類型。

我很樂意接受有關不同(更實用?)方法的建議,並希望得到您的意見。

回答

5

自定義變體類型的確是要走到這裏的途徑(通常在任何需要「X或Y」類型的地方)。但是,按照定義,您的函數看起來像它可能會返回一個數組,其中ColorSize混合在一起,但實際上它似乎只是希望它返回一個或另一個。如果是這樣,這是最好的體現在類型:

type Items = 
| Colors of string[] 
| Sizes of int[] 

let GetProp x ys = 
match x with 
| C -> Colors [| for y in ys -> y.Color |] 
| S -> Sizes [| for y in ys -> y.Size |] 

順便說一句,有沒有爲什麼你使用數組返回類型在這裏,而不是通常的懶惰序列(seq)什麼特別的原因?

+0

該數組是下一個我使用的外部庫所需的參數類型。我將如何從記錄列表轉到特定值的seq? – RobRolls 2009-12-19 08:48:29

+1

任何列表已經是一個seq,任何數組也是如此。在.NET中,seq是'IEnumerable '。如果你需要從任意一個隨機序列(也可能是一個懶序列)中創建一個數組或一個列表,那麼'Seq.toArray'和'Seq.toList'就可以完成。 – 2009-12-19 09:58:46

1

Go go gadget Array Comprehensions!

> [| for a in itemList do yield a.Size |];; 
val it : int [] = [|1; 2; 3|] 
> [| for a in itemList do yield a.Color |];; 
val it : string [] = [|"Red"; "Green"; "Blue"|] 

你並不需要一箇中間ItemTypeItemEnum數據結構。

+0

這不會幫助他,因爲他想寫將返回_different_元素類型的數組一個_single_功能,這取決於就其論點而言。 – 2009-12-19 07:56:42

4

您可以使用主動模式來查看數據形成的觀點幾點:

let (|AsColor|) (v: Item list) = [| for i in v -> i.Color |];; 

let (|AsSize|) (v: Item list) = [| for i in v -> i.Size |];; 

match itemList,itemList with 
    |AsColor ca, AsSize sa -> printfn "%A; %A" ca sa;; 
+0

我還沒有接觸到活動模式。有趣的,謝謝。 – RobRolls 2009-12-19 10:29:45

相關問題