代码根据它们的timestamp
值对两个输入序列(seq01和seq02)进行排序,并返回一个序列,该序列表示要按顺序读取哪个序列。
对于seq02的时间戳值小于seq01的时间戳值的情况,我们对返回的序列产生“2”,否则为“1”。这些表示在那时是采用seq01还是采用seq02使数据按顺序排列(按时间戳值)。
let mergeSeq (seq01:seq<_>) (seq02:seq<_>) =
seq {
use iter01 = seq01.GetEnumerator()
use iter02 = seq02.GetEnumerator()
while iter01.MoveNext() do
let _,_,time01 = iter01.Current
let _,_,time02 = iter02.Current
while time02 < time01 && iter02.MoveNext() do
yield "2"
yield "1"
}
为了在FSI中测试它,创建了两个序列a和b,a = {1; 3; 5; ...}和b = {0; 2; 4; ...}。因此let c = mergeSeq a b
的预期值应为{“2”,“1”,“2”,“1”......}。但是我收到此错误:error FS0001: The type ''a * 'b * 'c' does not match the type 'int'
修改
纠正后:
let mergeSeq (seq01:seq<_>) (seq02:seq<_>) =
seq {
use iter01 = seq01.GetEnumerator()
use iter02 = seq02.GetEnumerator()
while iter01.MoveNext() do
let time01 = iter01.Current
let time02 = iter02.Current
while time02 < time01 && iter02.MoveNext() do
yield "2"
yield "1"
}
运行此操作后,还有另一个错误:call MoveNext
。不知怎的,迭代没有被执行。
编辑2
let mergeRef (seq01:seq<_>) (seq02:seq<_>) =
seq{
use iter01 = seq01.GetEnumerator()
use iter02 = seq02.GetEnumerator()
iter01.MoveNext()
iter02.MoveNext()
let temp01 = ref iter01.Current //!!using mutable reference
let temp02 = ref iter02.Current
while iter01.MoveNext() do
while (iter02.MoveNext()) && ((!temp02) < (!temp01)) do
temp02 := iter02.Current
yield "2"
yield "1"
temp01 := iter01.Current
//if seq01 finishes before seq02
while iter02.MoveNext() do
yield "2"
}
答案 0 :(得分:3)
您需要更改
let _,_,time01 = iter01.Current
let _,_,time02 = iter02.Current
到
let time01 = iter01.Current
let time02 = iter02.Current
以便使用seq<int>
对代码进行类型检查。
我不明白你的意图。如果要比较两个序列中的每个对应元素对,可以使用更多功能解决方案:
let mergeSeq seq01 seq02 =
Seq.map2 (fun s1 s2 -> if s2 < s1 then "2" else "1") seq01 seq02
如果要合并两个已排序的序列,使用GetEnumerator
很好,但返回"2"
和"1"
对我没有意义。
答案 1 :(得分:2)
您已编写代码,就好像
一样a={1,1,1;2,2,2;3,3,3...}
只需使用
let time01 = iter01.Current
let time02 = iter02.Current
答案 2 :(得分:2)
编辑后......
在访问当前之前,您需要在2上调用MoveNext。当您在内循环中移动2时,您不会更新time02。并且你没有正确检查序列的结尾(例如,如果2结束但是1正在进行,你将尝试在结束后访问2)。
(这是家庭作业吗?)