合并/加入seqs的seq

时间:2009-02-02 07:30:55

标签: f# sequence

慢慢得到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',因为我知道我没有任何其他重复。

2 个答案:

答案 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