【问题标题】:How can I merge two lists of dates in F#?如何在 F# 中合并两个日期列表?
【发布时间】:2011-11-27 02:11:34
【问题描述】:

有两个日期列表(不能对列表顺序做出假设)

//first list
[date_a; date_b; date_c]
//second list
[date_A; date_B; date_C]

我正在寻找一个将以下内容作为条目列表返回的函数: 日期是唯一键(单个日期只会在列表中出现一次)

-> (date, true, true) in case both lists contained the date
-> (date, true, false) in case the first list contained the date
-> (date, false, true) in case the second list contained the date
(there will be no (date, false, false) entries)

【问题讨论】:

    标签: f#


    【解决方案1】:
    let showMembership l1 l2 = 
            let s1 = Set.ofList l1
            let s2 = Set.ofList l2
            Set.union s1 s2
                |> Set.map (fun d -> (d, Set.contains d s1, Set.contains d s2))
    

    请注意,这会返回一个 Set,但如果需要,您可以使用 List.ofSeq 创建一个列表

    【讨论】:

      【解决方案2】:

      使用一些简单的集合操作:

      open System
      
      //'a list -> 'a list -> ('a * bool * bool) list when 'a : comparison
      let merge dtl1 dtl2 =
          let dts1 = Set.ofList dtl1
          let dts2 = Set.ofList dtl2
      
          let dts1Only = dts1 - dts2
          let dts2Only = dts2 - dts1 
          let dtsBoth = Set.intersect dts1 dts2
      
          [
              for dt in dts1Only do
                  yield (dt,true,false)
      
              for dt in dts2Only do
                  yield (dt,false,true)
      
              for dt in dtsBoth do
                  yield (dt,true,true)
          ]
      

      这是一个例子:

      let dtl1 = 
         [DateTime.Today.AddDays(1.)
          DateTime.Today.AddDays(2.)
          DateTime.Today.AddDays(3.)
          DateTime.Today.AddDays(4.)
          DateTime.Today.AddDays(5.)
          DateTime.Today.AddDays(6.)]
      
      let dtl2 = 
         [DateTime.Today.AddDays(4.)
          DateTime.Today.AddDays(5.)
          DateTime.Today.AddDays(6.)
          DateTime.Today.AddDays(7.)
          DateTime.Today.AddDays(8.)
          DateTime.Today.AddDays(9.)]
      
      merge dtl1 dtl2
      

      【讨论】:

      • 可以直接使用方括号代替seq {}生成列表。
      • +1,虽然您的代码比 Lee 的更复杂,但速度更快。你的是 n log m + m log n + n log n + m log m 而 Lee 是 (n + m) log m + (n + m) log n。
      【解决方案3】:

      另一个用递归函数实现的例子(可能不像其他的那么简单和快速,但用不同的方法制作):

      let rec find (b: 'T list) (a: 'T) : bool * 'T list =
      
          match b with
          | [] -> false, b
          | h :: t ->
              if h = a then
                  true, t
              else 
                  let res, restB = a |> find t
                  res, h :: restB  
      
      let rec merge (a: 'T list) (b: 'T list) (order: bool) : ('T * bool * bool) list = 
          match a with
          | [] -> 
              if not(order) then
                  []
              else 
                  merge b a false 
          | h :: t ->
              let resA, newB = h |> find b
              (h, resA || order, resA || not(order)) :: merge t newB order 
      
      let Merge (a: 'T list) (b: 'T list) : ('T * bool * bool) list =
          merge a b true 
      

      对于:

      let dtl1 = 
         [DateTime.Today.AddDays(1.)
         DateTime.Today.AddDays(2.)
         DateTime.Today.AddDays(3.)
         DateTime.Today.AddDays(4.)
         DateTime.Today.AddDays(5.)
         DateTime.Today.AddDays(6.)]
      
      let dtl2 = 
         [DateTime.Today.AddDays(4.)
         DateTime.Today.AddDays(5.)
         DateTime.Today.AddDays(6.)
         DateTime.Today.AddDays(7.)
         DateTime.Today.AddDays(8.)
         DateTime.Today.AddDays(9.)]
      
      Merge dtl1 dtl2 
      

      给予:

      [(27.11.2011 0:00:00, true, false); (28.11.2011 0:00:00, true, false);
       (29.11.2011 0:00:00, true, false); (30.11.2011 0:00:00, true, true);
       (01.12.2011 0:00:00, true, true); (02.12.2011 0:00:00, true, true);
       (03.12.2011 0:00:00, false, true); (04.12.2011 0:00:00, false, true);
       (05.12.2011 0:00:00, false, true)]
      

      更新:合并功能被简化以使 DateTimes 的结果与其他答案相似

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-08-19
        • 1970-01-01
        • 1970-01-01
        • 2020-07-28
        • 2013-05-04
        • 2019-04-30
        • 1970-01-01
        相关资源
        最近更新 更多