groupWhen – a groupBy that compares consecutive values
groupBy has a minor problem: It always uses the first value of a group to decide whether a new value belongs to this group or the next. In several cases it would be more useful if it would take the last value of a group, thus always comparing consecutive values.
Example code:
groupWhen :: (a -> a -> Bool) -> [a] -> [[a]]
groupWhen _ [] = []
groupWhen _ [a] = [[a]]
groupWhen f (a:l) = if f a (head c) then (a:c):r
else [a]:c:r
where (c:r) = groupWhen f l
Uses:
groupWhen (\a b -> b - a < 5) [1,2,4,10,14,16,18] -- Finding holes in a increasing series, e.g. log time stamps (my real use case)
or
groupWhen (<) [1,2,3,2,10,12,10,11] -- Group into strictly increasing sublists
Note that for transitive and symetrical comparision functions f (such as (==)), groupBy f == groupWhen f.
It should probably go to Data.List
Trac metadata
| Trac field | Value |
|---|---|
| Version | 6.6.1 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | libraries (other) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | Unknown |
| Architecture | Unknown |