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

发布于 2024-08-15 14:37:15 字数 939 浏览 4 评论 0原文

我有一个记录列表,

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

我希望将我的记录列表转换为值数组,例如 [|"Red";"Green";"Blue"|] 或 [|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)

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

我愿意接受有关不同(更实用?)方法的建议,并且感谢您的意见。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

旧竹 2024-08-22 14:37:15

自定义变体类型确实是此处的方法(通常在您需要“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)有什么特殊原因吗?

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 and Size 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:

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 |]

By the way, is there any particular reason why you use array for return type here, rather than the usual lazy sequence (seq)?

爱殇璃 2024-08-22 14:37:15

您可以使用活动模式从以下几个角度查看数据:

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;;

You can use active patterns to see your data form few points of view:

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;;
樱花坊 2024-08-22 14:37:15

快去小工具数组推导式!

> [| 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 数据结构。

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"|]

You don't need an intermediate ItemType or ItemEnum data structure.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文