簡體   English   中英

按元素值拆分列表

[英]Split list by element value

我想根據特定值將字符串分成幾個塊。

例如列表[1; 2; 3; 0; 2; 4; 0; 5; 6; 0; 7] [1; 2; 3; 0; 2; 4; 0; 5; 6; 0; 7] [1; 2; 3; 0; 2; 4; 0; 5; 6; 0; 7]並且檢查元素0應該返回[[1; 2; 3]; [2; 4]; [5; 6]; [7]] [[1; 2; 3]; [2; 4]; [5; 6]; [7]]

如果下一個元素低於當前元素,我找到了一種拆分列表的方法

[1; 2; 3; 0; 2; 4; 0; 5; 6; 0; 7] [1; 2; 3; 0; 2; 4; 0; 5; 6; 0; 7]將返回[[1; 2; 3]; [0; 2; 4]; [0; 5; 6]; [0; 7]] [[1; 2; 3]; [0; 2; 4]; [0; 5; 6]; [0; 7]]

這是order ascending split的方法

let split2 lst =
    let folder (a, b) (cur, acc) = 
        match a with
        | _ when a < b -> a::cur, acc
        | _ -> [a], cur::acc

    let result = List.foldBack folder (List.pairwise lst) ([List.last lst], []) 
    (fst result)::(snd result)

printfn "%A" (split2 thelist)

這是我的修改:

let folder (a) (cur, acc) = 
    match a with
    | _ when a <> 0 -> a::cur, acc
    | _ -> [], cur::acc

let split lst =
    let result = List.foldBack folder (lst) ([], [])
    (fst result)::(snd result)

printfn "%A" (split thelist)

我不再需要pairwise ,因為我只逐個檢查元素,但是定義為[]currentacumulator讓我感到困惑,我不確定解決方案是否正確,即使我得到了所需的 output

有沒有更簡單的解決方案?

我會這樣做

let list = [1; 2; 3; 0; 2; 4; 0; 0; 5; 6; 0; 7]

list
|> Seq.fold (fun state number ->
    match number with
    | 0 -> []::state
    | x -> 
        match state with
        | [] -> [] // never here, actually
        | h::t -> [x::h]@t
    )
    [[]]
|> List.map List.rev
|> List.rev
|> List.filter (List.isEmpty >> not)

因此,您的 state 是一個列表列表(無論如何,這是您最終想要的)。 您需要反轉內部列表,然后是外部列表(如果您關心順序)。

我在最后添加了過濾器來處理連續 0 的結果,這會產生空列表。 您可以在 function 文件夾中處理它,它只會使代碼比現在更冗長。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM