TakeWhile, skipWhile combination

In F #, I find that when I want to use takeWhile

, I usually also want to use skipWhile

, that is, take the list prefix that satisfies the predicate and also remember the rest of the list for later processing.I don't think there is a standard library function that does both, but I can write one easily enough.

My question is, how should this combination be called? Obviously enough, there should be a standard name for it; what is it? The best I've thought of so far is split

what looks like splitAt

.

+3


source to share


3 answers


span

is another name I saw for this function. For example, in Haskell



+2


source


This part of your question stood out to me (emphasis mine):

take the list prefix that satisfies the predicate, and also remember the rest of the list for later processing

I assume you want to recurse with the rest of the list and then reapply that split function. This is what I wanted to do several times before. I originally wrote a function that I think you are describing, but on reflection I realized that there might be a more general way to think about this and avoid recursion entirely, which usually makes the code simpler. This is the function I came with.



module List =
    let groupAdjacentBy f xs =
        let mutable prevKey, i = None, 0
        xs
        |> List.groupBy (fun x ->
            let key = f x
            if prevKey <> Some key then
                i <- i + 1
                prevKey <- Some key
            (i, key))
        |> List.map (fun ((_, k), v) -> (k, v))

let even x = x % 2 = 0
List.groupAdjacentBy even [1; 3; 2; 5; 4; 6]
// [(false, [1; 3]); (true, [2]); (false, [5]); (true, [4; 6])]

      

I found this easier to call and more useful. This might work for your current problem. If you don't need the group keys, you can get rid of them by adding |> List.map snd

.

As much as I usually avoid mutation, using this here allowed me to use List.groupBy

and not write any more code.

+1


source


.slice

can capture a target of an adjacent range:

List.slice skipPredicate takePredicate

      

0


source







All Articles