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
.
source to share
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.
source to share