F# Split list into sublists based on comparison of adjacent elements

后端 未结 6 775
日久生厌
日久生厌 2020-12-03 17:46

I\'ve found this question on hubFS, but that handles a splitting criteria based on individual elements. I\'d like to split based on a comparison of adjacent elements, so the

6条回答
  •  [愿得一人]
    2020-12-03 18:31

    I like answers provided by @Joh and @Johan as these solutions seem to be most idiomatic and straightforward. I also like an idea suggested by @Shooton. However, each solution had their own drawbacks.
    I was trying to avoid:

    • Reversing lists
    • Unsplitting and joining back the temporary results
    • Complex match instructions
    • Even Seq.pairwise appeared to be redundant
    • Checking list for emptiness can be removed in cost of using Unchecked.defaultof<_> below

    Here's my version:

    let splitWhen f src =
        if List.isEmpty src then [] else
        src
        |> List.foldBack
            (fun el (prev, current, rest) ->
                if f el prev
                then el , [el]          , current :: rest
                else el , el :: current , rest
            )
            <| (List.head src, [], [])               // Initial value does not matter, dislike using Unchecked.defaultof<_>
        |> fun (_, current, rest) -> current :: rest // Merge temporary lists
        |> List.filter (not << List.isEmpty)         // Drop tail element
    

提交回复
热议问题