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 |