6

我从 CSV 文件中获取一系列记录。我想有选择地按日期和类型过滤这些记录,并有选择地合并满足某些条件的记录。可以选择按日期和类型进行过滤,使用Seq.filter. 但是,我想有选择地合并满足某些标准的记录。我有这个功能,我只是不知道如何有选择地将它应用到结果序列中。我不能使用 Seq.filter 因为 consolidate 对整个序列进行操作,而不是一次对一个项目进行操作。我可以用一个中间变量来解决它,我只是想知道是否有一种优雅的惯用方式来处理这个问题。

基本上我想知道一种有条件地应用正向管道序列中的一个(或多个)部分的方法。

这就是我想要的伪代码(options包含命令行参数):

let x =
    getRecords options.filePath
    |> Seq.filter (fun r -> if options.Date.HasValue then
                            r.Date.Date = options.Date.Value.Date else true)
    |> Seq.filter (fun r -> if not(String.IsNullOrEmpty(options.Type)) then
                            r.Type = options.Type else true)
    if options.ConsolidateRecords then
        |> consolidateRecords
4

3 回答 3

9

You can use an if ... else expression with the identity function in else clause:

let x =
    getRecords options.filePath
    |> (* ... bunch of stuff ... *)
    |> (if options.ConsolidateRecords then consolidateRecords else id)
    |> (* ... optionally more stuff ... *)
于 2013-07-24T04:50:38.387 回答
5

我会做类似的事情

let x =
    getRecords options.filePath
    |> Seq.filter (fun r -> if options.Date.HasValue then
                            r.Date.Date = options.Date.Value.Date else true)
    |> Seq.filter (fun r -> if not(String.IsNullOrEmpty(options.Type)) then
                            r.Type = options.Type else true)
    |> fun x ->
         if options.ConsolidateRecords then x |> consolidateRecords
         else ....
于 2013-07-23T23:24:14.603 回答
3

您还可以隐藏先前的定义x

let x =
    getRecords options.filePath
    |> Seq.filter (fun r -> 
        not options.Date.HasValue || r.Date.Date = options.Date.Value.Date)
    |> Seq.filter (fun r -> 
        String.IsNullOrEmpty(options.Type) || r.Type = options.Type)
let x = if options.ConsolidateRecords then consolidateRecords x else x
于 2013-07-24T14:23:45.917 回答