从F#中的lambda表达式返回不同类型的数组

时间:2009-12-19 06:03:45

标签: arrays f# lambda types record

我有一份记录列表

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)

但它不喜欢两种不同的返回类型。

我愿意接受有关不同(更多功能性)方法的建议,并希望得到您的意见。

3 个答案:

答案 0 :(得分: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),有什么特别的原因吗?

答案 1 :(得分: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;;

答案 2 :(得分: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数据结构。

相关问题