慢慢得到List匹配和尾递归的悬念,我需要一个函数来“拼接”一个列表列表,一起留下中间值(比解释更容易显示):
合并[[1; 2; 3]; [3; 4; 5]; [5; 6; 7]] // - > [1; 2; 3; 4; 5; 6; 7]
List.merge函数的代码如下所示:
///Like concat, but removes first value of each inner list except the first one
let merge lst =
let rec loop acc lst =
match lst with
| [] -> acc
| h::t ->
match acc with
| [] -> loop (acc @ h) t
| _ -> loop (acc @ (List.tl h)) t //first time omit first value
loop [] lst
(好吧,它不太像concat,因为它只处理两个级别的列表)
问题:如何为Seqs Seqs做这个(不使用可变标志)?
更新(来自Juliet的评论): 我的代码创建了由“段”组成的“路径”,它们基于选项类型:
type SegmentDef = Straight of float | Curve of float * float
let Project sampleinterval segdefs = //('clever' code here)
当我执行List.map(项目1)ListOfSegmentDefs时,我得到一个列表,其中每个段开始于前一个段结束的同一点。我想一起加入这些列表以获得一个Path,只保留每个重叠的“顶部/尾部” - 但我不需要做'Set',因为我知道我没有任何其他重复。
答案 0 :(得分:4)
这与您的第一个解决方案基本相同,但更简洁:
let flatten l =
seq {
yield Seq.hd (Seq.hd l) (* first item of first list *)
for a in l do yield! (Seq.skip 1 a) (* other items *)
}
[编辑添加]:
如果您需要此代码的List版本,请在方法的末尾使用追加|> Seq.to_list
:
let flatten l =
seq {
yield Seq.hd (Seq.hd l) (* first item of first list *)
for a in l do yield! (Seq.skip 1 a) (* other items *)
} |> Seq.to_list
答案 1 :(得分:4)
let merge = function
| [] -> []
| xs::xss -> xs @ [for _::xs in xss do yield! xs]
或:
let merge = function
| [] -> []
| xs::xss -> xs @ List.collect List.tail xss