i have a List of records
type Item = { Color : string; Size : int}
let itemList = [{Color="Red"; Size=1};
{Color="Green"; Size=2};
{Color="Blue"; Size=3};]
I am looking to get turn my list of records into an array of values like [|"Red";"Green";"Blue"|] or [|1;2;3|]
I can sorta get there like this
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))
but when I call GetProp S itemList
I get back [|Size 1; Size 2; Size 3|]. Useful but not exactly what I'm looking for.
I've tried the following
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)
but it doesn't like the two different return types.
I'm open to suggestions on different (more functional?) ways of doing this and would appreciate your input.
Go go gadget Array Comprehensions!
You don't need an intermediate
ItemType
orItemEnum
data structure.You can use active patterns to see your data form few points of view:
A custom variant type is indeed the way to go here (and generally wherever you need a type that is "either X or Y"). However, as defined, your function looks like it might return an array in which
Color
andSize
are mixed, but in practice it seems that you only want it to return one or the other. If so, this is best reflected in the types:By the way, is there any particular reason why you use array for return type here, rather than the usual lazy sequence (
seq
)?