简体   繁体   中英

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] and check element 0 should return [[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]]

This is the method for the 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

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). 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. You could handle that in the folder function, it will just make the code a bit more verbose than it already is.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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