Skip to content

Commit

Permalink
Add gatherEquals function. (#114)
Browse files Browse the repository at this point in the history
* Added gatherEquals function.

* Added gatherEqualsBy and gatherEqualsWith.

* Return non-empty list.

* gatherEqualsWith => gatherWith.

* Fixed documentation.

* Added gatherEqualsBy and gatherWith to @docs.

* Added information about element ordering.

* Format gather examples for elm-verify-examples
  • Loading branch information
robinheghan authored and Chadtech committed Oct 8, 2018
1 parent 8b4c304 commit 55d1bce
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 3 deletions.
57 changes: 54 additions & 3 deletions src/List/Extra.elm
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ module List.Extra exposing
, intercalate, transpose, subsequences, permutations, interweave, cartesianProduct
, foldl1, foldr1, indexedFoldl, indexedFoldr
, scanl, scanl1, scanr, scanr1, mapAccuml, mapAccumr, unfoldr, iterate, initialize, cycle
, splitAt, splitWhen, takeWhileRight, dropWhileRight, span, break, stripPrefix, group, groupWhile, inits, tails, select, selectSplit
, splitAt, splitWhen, takeWhileRight, dropWhileRight, span, break, stripPrefix, group, groupWhile, inits, tails, select, selectSplit, gatherEquals, gatherEqualsBy, gatherWith
, isPrefixOf, isSuffixOf, isInfixOf, isSubsequenceOf, isPermutationOf
, notMember, find, elemIndex, elemIndices, findIndex, findIndices, count
, zip, zip3
, lift2, lift3, lift4
, groupsOf, groupsOfWithStep, groupsOfVarying, greedyGroupsOf, greedyGroupsOfWithStep
)

{-| Convenience functions for working with List
Expand All @@ -36,7 +36,7 @@ module List.Extra exposing
# Sublists
@docs splitAt, splitWhen, takeWhileRight, dropWhileRight, span, break, stripPrefix, group, groupWhile, inits, tails, select, selectSplit
@docs splitAt, splitWhen, takeWhileRight, dropWhileRight, span, break, stripPrefix, group, groupWhile, inits, tails, select, selectSplit, gatherEquals, gatherEqualsBy, gatherWith
# Predicates
Expand Down Expand Up @@ -1857,3 +1857,54 @@ greedyGroupsOfWithStep size step xs =

else
[]

{-| Group equal elements together. This is different from `group` as each sublist
will contain *all* equal elements of the original list. Elements will be grouped
in the same order as they appear in the original list. The same applies to elements
within each group.
gatherEquals [1,2,1,3,2]
--> [(1,[1]),(2,[2]),(3,[])]
-}
gatherEquals : List a -> List (a, List a)
gatherEquals list =
gatherWith (==) list


{-| Group equal elements together. A function is applied to each element of the list
and then the equality check is performed against the results of that function evaluation.
Elements will be grouped in the same order as they appear in the original list. The
same applies to elements within each group.
gatherEqualsBy .age [{age=25},{age=23},{age=25}]
--> [({age=25},[{age=25}]),({age=23},[])]
-}
gatherEqualsBy : (a -> b) -> List a -> List (a, List a)
gatherEqualsBy extract list =
gatherWith (\a b -> (extract a) == (extract b)) list


{-| Group equal elements together using a custom equality function. Elements will be
grouped in the same order as they appear in the original list. The same applies to
elements within each group.
gatherWith (==) [1,2,1,3,2]
--> [(1,[1]),(2,[2]),(3,[])]
-}
gatherWith : (a -> a -> Bool) -> List a -> List (a, List a)
gatherWith testFn list =
let
helper : List a -> List (a,List a) -> List (a, List a)
helper scattered gathered =
case scattered of
[] ->
List.reverse gathered

toGather :: population ->
let
( gathering, remaining ) =
List.partition (testFn toGather) population
in
helper remaining <| (toGather, gathering) :: gathered
in
helper list []
57 changes: 57 additions & 0 deletions tests/Tests.elm
Original file line number Diff line number Diff line change
Expand Up @@ -685,4 +685,61 @@ all =
\() ->
Expect.equal (setIf (\x -> modBy 2 x == 0) 0 [ 17, 8, 2, 9 ]) [ 17, 0, 0, 9 ]
]
, describe "gatherEquals"
[ test "empty list" <|
\() ->
gatherEquals []
|> Expect.equal []
, test "single element" <|
\() ->
gatherEquals [ 1 ]
|> Expect.equal [ (1, []) ]
, test "proper test" <|
\() ->
gatherEquals [ 1, 2, 1, 2, 3, 4, 1 ]
|> Expect.equal
[ ( 1, [ 1, 1 ])
, ( 2, [ 2 ])
, ( 3, [])
, ( 4, [])
]
]
, describe "gatherEqualsBy"
[ test "empty list" <|
\() ->
gatherEqualsBy identity []
|> Expect.equal []
, test "single element" <|
\() ->
gatherEqualsBy identity [ 1 ]
|> Expect.equal [ (1, []) ]
, test "proper test" <|
\() ->
gatherEqualsBy identity [ 1, 2, 1, 2, 3, 4, 1 ]
|> Expect.equal
[ ( 1, [ 1, 1 ])
, ( 2, [ 2 ])
, ( 3, [])
, ( 4, [])
]
]
, describe "gatherWith"
[ test "empty list" <|
\() ->
gatherWith (==) []
|> Expect.equal []
, test "single element" <|
\() ->
gatherWith (==) [ 1 ]
|> Expect.equal [ (1, []) ]
, test "proper test" <|
\() ->
gatherWith (==) [ 1, 2, 1, 2, 3, 4, 1 ]
|> Expect.equal
[ ( 1, [ 1, 1 ])
, ( 2, [ 2 ])
, ( 3, [])
, ( 4, [])
]
]
]

0 comments on commit 55d1bce

Please sign in to comment.