Skip to content

Commit 7498594

Browse files
Revise groupAllBy to just use an Ordering function (#191)
Co-authored-by: JordanMartinez <[email protected]>
1 parent d6b28b3 commit 7498594

File tree

5 files changed

+22
-18
lines changed

5 files changed

+22
-18
lines changed

CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Breaking changes:
88
- Update project and deps to PureScript v0.15.0 (#203 by @JordanMartinez)
99
- Drop deprecated `MonadZero` instance (#205 by @JordanMartinez)
1010
- Drop deprecated `group'` and `mapWithIndex` (#206 by @JordanMartinez)
11+
- Change `groupAllBy` to use a comparison function (#191)
1112

1213
New features:
1314

@@ -43,7 +44,7 @@ Breaking changes:
4344

4445
New features:
4546
- Added `nubEq`/`nubByEq` (#179)
46-
- Added `groupAllBy` (#182, #191)
47+
- Added `groupAllBy` (#182)
4748
- Added `Eq1` and `Ord1` instances to `NonEmptyList` and `LazyNonEmptyList` (#188)
4849

4950
Bugfixes:

src/Data/List.purs

+7-8
Original file line numberDiff line numberDiff line change
@@ -611,17 +611,16 @@ groupBy _ Nil = Nil
611611
groupBy eq (x : xs) = case span (eq x) xs of
612612
{ init: ys, rest: zs } -> NEL.NonEmptyList (x :| ys) : groupBy eq zs
613613

614-
-- | Group equal elements of a list into lists, using the specified
615-
-- | equivalence relation to determine equality.
616-
-- |
617-
-- | For example,
614+
-- | Sort, then group equal elements of a list into lists, using the provided comparison function.
618615
-- |
619616
-- | ```purescript
620-
-- | groupAllBy (\a b -> odd a && odd b) (1 : 3 : 2 : 4 : 3 : 3 : Nil) ==
621-
-- | (NonEmptyList (NonEmpty 1 Nil)) : (NonEmptyList (NonEmpty 2 Nil)) : (NonEmptyList (NonEmpty 3 (3 : 3 : Nil))) : (NonEmptyList (NonEmpty 4 Nil)) : Nil
617+
-- | groupAllBy (compare `on` (_ `div` 10)) (32 : 31 : 21 : 22 : 11 : 33 : Nil) ==
618+
-- | NonEmptyList (11 :| Nil) : NonEmptyList (21 :| 22 : Nil) : NonEmptyList (32 :| 31 : 33) : Nil
622619
-- | ```
623-
groupAllBy :: forall a. Ord a => (a -> a -> Boolean) -> List a -> List (NEL.NonEmptyList a)
624-
groupAllBy p = groupBy p <<< sort
620+
-- |
621+
-- | Running time: `O(n log n)`
622+
groupAllBy :: forall a. (a -> a -> Ordering) -> List a -> List (NEL.NonEmptyList a)
623+
groupAllBy p = groupBy (\x y -> p x y == EQ) <<< sortBy p
625624

626625
-- | Returns a lists of elements which do and do not satisfy a predicate.
627626
-- |

src/Data/List/NonEmpty.purs

+1-1
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ groupAll = wrappedOperation "groupAll" L.groupAll
260260
groupBy :: forall a. (a -> a -> Boolean) -> NonEmptyList a -> NonEmptyList (NonEmptyList a)
261261
groupBy = wrappedOperation "groupBy" <<< L.groupBy
262262

263-
groupAllBy :: forall a. Ord a => (a -> a -> Boolean) -> NonEmptyList a -> NonEmptyList (NonEmptyList a)
263+
groupAllBy :: forall a. (a -> a -> Ordering) -> NonEmptyList a -> NonEmptyList (NonEmptyList a)
264264
groupAllBy = wrappedOperation "groupAllBy" <<< L.groupAllBy
265265

266266
partition :: forall a. (a -> Boolean) -> NonEmptyList a -> { yes :: L.List a, no :: L.List a }

test/Test/Data/List.purs

+8-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module Test.Data.List (testList) where
33
import Prelude
44

55
import Data.Array as Array
6-
import Data.Foldable (foldMap, foldl)
6+
import Data.Foldable (class Foldable, foldMap, foldl)
77
import Data.FoldableWithIndex (foldMapWithIndex, foldlWithIndex, foldrWithIndex)
88
import Data.Function (on)
99
import Data.List (List(..), Pattern(..), alterAt, catMaybes, concat, concatMap, delete, deleteAt, deleteBy, drop, dropEnd, dropWhile, elemIndex, elemLastIndex, filter, filterM, findIndex, findLastIndex, foldM, fromFoldable, group, groupAll, groupAllBy, groupBy, head, init, insert, insertAt, insertBy, intersect, intersectBy, last, length, mapMaybe, modifyAt, nub, nubBy, nubByEq, nubEq, null, partition, range, reverse, singleton, snoc, sort, sortBy, span, stripPrefix, tail, take, takeEnd, takeWhile, transpose, uncons, union, unionBy, unsnoc, unzip, updateAt, zip, zipWith, zipWithA, (!!), (..), (:), (\\))
@@ -23,7 +23,11 @@ import Test.Assert (assert)
2323

2424
testList :: Effect Unit
2525
testList = do
26-
let l = fromFoldable
26+
let
27+
l = fromFoldable
28+
29+
nel :: forall f a. Foldable f => a -> f a -> NEL.NonEmptyList a
30+
nel x xs = NEL.NonEmptyList $ x :| fromFoldable xs
2731

2832
log "strip prefix"
2933
assert $ stripPrefix (Pattern (1:Nil)) (1:2:Nil) == Just (2:Nil)
@@ -272,8 +276,8 @@ testList = do
272276
log "groupBy should group consecutive equal elements into lists based on an equivalence relation"
273277
assert $ groupBy (\x y -> odd x && odd y) (l [1, 1, 2, 2, 3, 3]) == l [NEL.NonEmptyList (1 :| l [1]), NEL.singleton 2, NEL.singleton 2, NEL.NonEmptyList (3 :| l [3])]
274278

275-
log "groupAllBy should group equal elements into lists based on an equivalence relation"
276-
assert $ groupAllBy (\x y -> odd x && odd y) (l [1, 3, 2, 4, 3, 3]) == l [NEL.singleton 1, NEL.singleton 2, NEL.NonEmptyList (3 :| l [3, 3]), NEL.singleton 4]
279+
log "groupAllBy should sort then group equal elements into lists based on a comparison function"
280+
assert $ groupAllBy (compare `on` (_ `div` 10)) (l [32, 31, 21, 22, 11, 33]) == l [nel 11 [], nel 21 [22], nel 32 [31, 33]]
277281

278282
log "partition should separate a list into a tuple of lists that do and do not satisfy a predicate"
279283
let partitioned = partition (_ > 2) (l [1, 5, 3, 2, 4])

test/Test/Data/List/NonEmpty.purs

+4-4
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ import Test.Assert (assert)
2121
testNonEmptyList :: Effect Unit
2222
testNonEmptyList = do
2323
let
24-
nel :: f a. Foldable f => a -> f a -> NEL.NonEmptyList a
24+
nel :: forall f a. Foldable f => a -> f a -> NEL.NonEmptyList a
2525
nel x xs = NEL.NonEmptyList $ x :| L.fromFoldable xs
26-
l :: f a. Foldable f => f a -> L.List a
26+
l :: forall f a. Foldable f => f a -> L.List a
2727
l = L.fromFoldable
2828

2929
log "singleton should construct a non-empty list with a single value"
@@ -173,8 +173,8 @@ testNonEmptyList = do
173173
log "groupBy should group consecutive equal elements into lists based on an equivalence relation"
174174
assert $ NEL.groupBy (\x y -> odd x && odd y) (nel 1 [1, 2, 2, 3, 3]) == nel (nel 1 [1]) [nel 2 [], nel 2 [], nel 3 [3]]
175175

176-
log "groupAllBy should group equal elements into lists based on an equivalence relation"
177-
assert $ NEL.groupAllBy (\x y -> odd x && odd y) (nel 1 [3, 2, 4, 3, 3]) == nel (nel 1 []) [nel 2 [], nel 3 [3, 3], nel 4 []]
176+
log "groupAllBy should sort then group equal elements into lists based on a comparison function"
177+
assert $ NEL.groupAllBy (compare `on` (_ `div` 10)) (nel 32 [31, 21, 22, 11, 33]) == nel (nel 11 []) [nel 21 [22], nel 32 [31, 33]]
178178

179179
log "partition should separate a list into a tuple of lists that do and do not satisfy a predicate"
180180
let partitioned = NEL.partition (_ > 2) (nel 1 [5, 3, 2, 4])

0 commit comments

Comments
 (0)