简体   繁体   English

按元素值拆分列表

[英]Split list by element value

I want to split a string in several chunks based on a specific value.我想根据特定值将字符串分成几个块。

For example the list [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] and check element 0 should return [[1; 2; 3]; [2; 4]; [5; 6]; [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]]

I've found a method that splits a list if the next element is lower than the current one如果下一个元素低于当前元素,我找到了一种拆分列表的方法

[1; 2; 3; 0; 2; 4; 0; 5; 6; 0; 7] [1; 2; 3; 0; 2; 4; 0; 5; 6; 0; 7] would return [[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]]

This is the method for the order ascending split这是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)

And this is my modification:这是我的修改:

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)

I no longer need the pairwise as I only check element by element, but the current and acumulator defined as [] confuse me and I am not sure if the solution is correct, even though I get the desired output我不再需要pairwise ,因为我只逐个检查元素,但是定义为[]currentacumulator让我感到困惑,我不确定解决方案是否正确,即使我得到了所需的 output

Is there an easier solution for this?有没有更简单的解决方案?

I would do it like this我会这样做

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)

So, your state is a list of lists (which is what you ultimately want, anyway).因此,您的 state 是一个列表列表(无论如何,这是您最终想要的)。 You need to reverse the inner lists, then the outer one (if you care about order).您需要反转内部列表,然后是外部列表(如果您关心顺序)。

I added the filter at the end to deal with the result of consecutive 0's, which produce empty lists.我在最后添加了过滤器来处理连续 0 的结果,这会产生空列表。 You could handle that in the folder function, it will just make the code a bit more verbose than it already is.您可以在 function 文件夹中处理它,它只会使代码比现在更冗长。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM