F#:不过滤任何内容,只保留部分内容
关于如何有效分组/筛选列表/顺序的快速问题F#:不过滤任何内容,只保留部分内容,f#,F#,关于如何有效分组/筛选列表/顺序的快速问题 仅筛选可选字段不是“无”的记录 删除“option”参数以简化未来的流程(因为没有筛选出任何流程) 团体(我相信这没有问题) 我使用的是最好的方法吗 谢谢 type tmp = { A : string B : int option } type tmp2 = { A : string B : int } let inline getOrElse (dft: 'a) (x: 'a option) = ma
type tmp = {
A : string
B : int option }
type tmp2 = {
A : string
B : int }
let inline getOrElse (dft: 'a) (x: 'a option) =
match x with
| Some v -> v
| _ -> dft
let getGrouped (l: tmp list) =
l |> List.filter (fun a -> a.B.IsSome)
|> List.map (fun a -> {A = a.A ; B = (getOrElse 0 (a.B)) })
|> List.groupBy (fun a -> a.A)
简单的解决方案是使用一个属性,即选项可以转换为包含一个或零个元素的列表,然后您可以定义如下函数:
let t1 ({A=a; B=b} : tmp) =
match b with
| (Some i) -> [{ A = a; B= i}]
| _ -> []
let getGrouped (l: tmp list) =
l |> List.collect t1
|> List.groupBy (fun a -> a.A)
当涉及到
选项
时,map+filter
最自然的方法是使用choose
,这将结合这两个操作,并从过滤输出中删除选项包装
您的示例如下所示:
let getGrouped (l: tmp list) =
l
|> List.choose (fun a ->
a.B
|> Option.map (fun b -> {A = a.A; B = b})
|> List.groupBy (fun a -> a.A)
谢谢,我喜欢这种方法。至少这些函数在签名方面比Deedle的函数更清晰。getOrElse函数是标准Option.defaultValue函数的翻版,但由于过滤器删除了B为“无”的列表项,您不需要它,因为B必须始终是一些int。