4

リストの一致と末尾再帰のこつをゆっくりとつかむと、リストのリストをまとめて「つなぎ合わせる」関数が必要になりました (説明するよりも表示する方が簡単です)。

マージ [[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

(わかりました、2 レベルのリストしか処理しないため、concat とはまったく異なります)

質問: Seq of Seqs に対してこれを行うには (可変フラグを使用せずに)?

UPDATE(ジュリエットからの再コメント):私のコードは、オプションタイプに基づく「セグメント」で構成される「パス」を作成します:

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

List.map (Project 1.) ListOfSegmentDefs を実行すると、各セグメントが前のセグメントが終了するのと同じポイントで始まるリストが返されます。これらのリストを結合してパスを取得し、各オーバーラップの「トップ/テール」のみを保持しますが、「セット」を行う必要はありません。他に重複がないことがわかっているからです。

4

2 に答える 2

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
于 2010-07-08T23:22:01.640 に答える
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 *)
    }

[編集して追加]:

このコードのリスト バージョンが必要な場合|> 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
于 2009-02-03T03:34:26.090 に答える