按元素值拆分列表

富恩特斯

我想根据特定值将一个字符串分成几个块。

例如 list[1; 2; 3; 0; 2; 4; 0; 5; 6; 0; 7]和 check 元素0应该返回[[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]]

这是方法 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定义为[]让我感到困惑,我不确定解决方案是否正确,即使我得到了所需的输出

有没有更简单的解决方案?

吉姆·弗耶

我会这样做

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)

因此,您的状态是一个列表列表(无论如何,这就是您最终想要的)。您需要反转内部列表,然后反转外部列表(如果您关心顺序)。

我在最后添加了过滤器来处理连续 0 的结果,这会产生空列表。您可以在文件夹函数中处理它,它只会使代码比现在更冗长。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章