Domanda

Comprendendo lentamente la corrispondenza dell'elenco e la ricorsione della coda, avevo bisogno di una funzione che "ricama" un elenco di elenchi lasciando fuori valori intermedi (più facile da mostrare che da spiegare):

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

Il codice per la funzione List.merge è simile al seguente:

///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, non è proprio come concat, perché gestisce solo due livelli di elenco)

Domanda: come fare per un Seq di Seq (senza usare un flag mutabile)?

AGGIORNAMENTO (re commento da Juliet): Il mio codice crea "percorsi" composti da "segmenti" basati su un tipo di opzione:

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

Quando eseguo un List.map (Progetto 1.) ListOfSegmentDefs, torno indietro un elenco in cui ogni segmento inizia nello stesso punto in cui termina il segmento precedente. Voglio unire queste liste per ottenere un Path, mantenendo solo la 'top / tail' di ogni sovrapposizione, ma non ho bisogno di fare un 'Set', perché so che non ho altri duplicati.

È stato utile?

Soluzione

Questa è sostanzialmente la stessa della tua prima soluzione, ma un po 'più concisa:

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

[Modifica per aggiungere]:

Se hai bisogno di una versione dell'elenco di questo codice, usa append |> Seq.to_list alla fine del tuo metodo:

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

Altri suggerimenti

let merge = function
  | [] -> []
  | xs::xss -> xs @ [for _::xs in xss do yield! xs]

o

let merge = function
  | [] -> []
  | xs::xss -> xs @ List.collect List.tail xss
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top