合并/加入seq [英] Merge/join seq of seqs

查看:70
本文介绍了合并/加入seq的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

慢慢地掌握列表匹配和尾部递归的技巧,我需要一个将列表列表缝合"在一起的函数,从而省去了中间值(更容易显示而不是说明):

合并[[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,因为它只处理两个级别的列表)

问题:如何针对Seq of Seqs(不使用可变标志)执行此操作?

更新(来自朱丽叶的评论): 我的代码根据选项类型创建由段"组成的路径":

type SegmentDef = Straight of float | Curve of float * float
let Project sampleinterval segdefs = //('clever' code here)

当我执行List.map(项目1).ListOfSegmentDefs时,我会得到一个列表,其中每个段从上一个段结束的同一点开始.我想将这些列表连接在一起以获得路径,只保留每个重叠的顶部/尾部"-但我不需要做设置",因为我知道我没有其他重复项.

解决方案

这与您的第一个解决方案基本相同,但更为简洁:

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 *)
    }

:

如果您需要此代码的列表版本,请在方法末尾使用append |> 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

Slowly getting the hang of List matching and tail recursion, I needed a function which 'stitches' a list of lists together leaving off intermediate values (easier to show than explain):

merge [[1;2;3];[3;4;5];[5;6;7]] //-> [1;2;3;4;5;6;7]

The code for the List.merge function looks like this:

///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

(OK, it's not quite like concat, because it only handles two levels of list)

Question: How to do this for a Seq of Seqs (without using a mutable flag)?

UPDATE (re comment from Juliet): My code creates 'paths' composed of 'segments' which are based on an option type:

type SegmentDef = Straight of float | Curve of float * float
let Project sampleinterval segdefs = //('clever' code here)

When I do a List.map (Project 1.) ListOfSegmentDefs, I get back a list where each segment begins on the same point where the previous segment ends. I want to join these lists together to get a Path, keeping only the 'top/tail' of each overlap - but I don't need to do a 'Set', because I know that I don't have any other duplicates.

解决方案

This is essentially the same as your first solution, but a little more succinct:

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 *)
    }

[Edit to add]:

If you need a List version of this code, use append |> Seq.to_list at the end of your method:

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

这篇关于合并/加入seq的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆