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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With