【问题标题】:Conditionally apply filter in forward pipe chain in F#?有条件地在 F# 的正向管道链中应用过滤器?
【发布时间】:2013-07-23 23:06:42
【问题描述】:

我从 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

【问题讨论】:

    标签: f# conditional-statements


    【解决方案1】:

    您可以在else 子句中使用带有标识函数的if ... else 表达式:

    let x =
        getRecords options.filePath
        |> (* ... bunch of stuff ... *)
        |> (if options.ConsolidateRecords then consolidateRecords else id)
        |> (* ... optionally more stuff ... *)
    

    【讨论】:

      【解决方案2】:

      我会做类似的事情

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

      【讨论】:

      • 我喜欢。所以当options.ConsolidateRecords 为假时什么都不做,那么else 子句只会返回x?还是你有别的想法?
      • 在我投赞成票之前,您想截取您的 7777 分数吗?我觉得很糟糕,赞成它大声笑
      • @User 要么返回 x 要么继续处理,无论你本来会做什么。
      【解决方案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
      

      【讨论】:

        猜你喜欢
        • 2021-03-25
        • 2021-12-11
        • 2021-04-14
        • 1970-01-01
        • 1970-01-01
        • 2015-07-20
        • 2013-06-16
        • 2021-11-26
        • 1970-01-01
        相关资源
        最近更新 更多