如何在F#中合并两个日期列表?

如何在F#中合并两个日期列表?,f#,F#,有两个日期列表(不能假设列表顺序) 我正在寻找一个函数,该函数以条目列表的形式返回以下内容: 日期是唯一键(单个日期在列表中仅显示一次) 使用一些简单的集合操作: 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 d

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

我正在寻找一个函数,该函数以条目列表的形式返回以下内容: 日期是唯一键(单个日期在列表中仅显示一次)


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

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


注意:这将返回一个集合,但如果需要,您可以使用
List.ofSeq
创建一个列表另一个使用递归函数实现的示例(可能不像其他示例那样简单和快速,但采用不同的方法):

以及:

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

更新:合并函数被简化为使结果中的日期时间顺序与其他答案类似

您可以直接使用方括号而不是seq{}.+1生成列表,虽然您的代码比Lee的更复杂,但速度更快。你的是n log m+m log n+n log n+m log m,而李的是(n+m)log m+(n+m)log n。
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))
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)]