如何在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)]