From ec6102a0bc45f541041c988363564e35e25cf584 Mon Sep 17 00:00:00 2001 From: Robin Heggelund Hansen Date: Wed, 26 Sep 2018 20:20:26 +0200 Subject: [PATCH 1/8] Added gatherEquals function. --- src/List/Extra.elm | 26 +++++++++++++++++++++++++- tests/Tests.elm | 19 +++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/List/Extra.elm b/src/List/Extra.elm index 5afe67b..53f7d05 100644 --- a/src/List/Extra.elm +++ b/src/List/Extra.elm @@ -18,6 +18,7 @@ module List.Extra , findIndices , foldl1 , foldr1 + , gatherEquals , getAt , greedyGroupsOf , greedyGroupsOfWithStep @@ -109,7 +110,7 @@ module List.Extra # 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 # Predicates @@ -1672,3 +1673,26 @@ greedyGroupsOfWithStep size step xs = List.take size xs :: 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. + + gatherEquals [1,2,1,3,2] == [[1,1],[2,2],[3]] +-} +gatherEquals : List a -> List (List a) +gatherEquals list = + let + helper : List a -> List (List a) -> List (List a) + helper scattered gathered = + case scattered of + [] -> + List.reverse gathered + + toGather :: population -> + let + ( gathering, remaining ) = + List.partition (\e -> e == toGather) population + in + helper remaining <| (toGather :: gathering) :: gathered + in + helper list [] diff --git a/tests/Tests.elm b/tests/Tests.elm index afd5edd..299cdb3 100644 --- a/tests/Tests.elm +++ b/tests/Tests.elm @@ -685,4 +685,23 @@ 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 ] + ] + ] ] From 051aa895c5edf3e363348ea741b4824503890ff6 Mon Sep 17 00:00:00 2001 From: Robin Heggelund Hansen Date: Sat, 29 Sep 2018 23:28:17 +0200 Subject: [PATCH 2/8] Added gatherEqualsBy and gatherEqualsWith. --- src/List/Extra.elm | 23 ++++++++++++++++++++++- tests/Tests.elm | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/src/List/Extra.elm b/src/List/Extra.elm index 53f7d05..02bbe1c 100644 --- a/src/List/Extra.elm +++ b/src/List/Extra.elm @@ -19,6 +19,8 @@ module List.Extra , foldl1 , foldr1 , gatherEquals + , gatherEqualsBy + , gatherEqualsWith , getAt , greedyGroupsOf , greedyGroupsOfWithStep @@ -1681,6 +1683,25 @@ will contain *all* equal elements of the original list. -} gatherEquals : List a -> List (List a) gatherEquals list = + gatherEqualsWith (==) 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. + + gatherEqualsBy .name [{age=25},{age=23},{age=25}] == [[{age=25},{age=25}],[{age=23}]] +-} +gatherEqualsBy : (a -> b) -> List a -> List (List a) +gatherEqualsBy extract list = + gatherEqualsWith (\a b -> (extract a) == (extract b)) list + + +{-| Group equal elements together using a custom equality function. + + gatherEquals (==) [1,2,1,3,2] == [[1,1],[2,2],[3]] +-} +gatherEqualsWith : (a -> a -> Bool) -> List a -> List (List a) +gatherEqualsWith testFn list = let helper : List a -> List (List a) -> List (List a) helper scattered gathered = @@ -1691,7 +1712,7 @@ gatherEquals list = toGather :: population -> let ( gathering, remaining ) = - List.partition (\e -> e == toGather) population + List.partition (testFn toGather) population in helper remaining <| (toGather :: gathering) :: gathered in diff --git a/tests/Tests.elm b/tests/Tests.elm index 299cdb3..6dc40b3 100644 --- a/tests/Tests.elm +++ b/tests/Tests.elm @@ -704,4 +704,42 @@ all = , [ 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 "gatherEqualsWith" + [ test "empty list" <| + \() -> + gatherEqualsWith (==) [] + |> Expect.equal [] + , test "single element" <| + \() -> + gatherEqualsWith (==) [ 1 ] + |> Expect.equal [ [ 1 ] ] + , test "proper test" <| + \() -> + gatherEqualsWith (==) [ 1, 2, 1, 2, 3, 4, 1 ] + |> Expect.equal + [ [ 1, 1, 1 ] + , [ 2, 2 ] + , [ 3 ] + , [ 4 ] + ] + ] ] From 8f65c793977dbaebf7972e5216284ef3491bd2c6 Mon Sep 17 00:00:00 2001 From: Robin Heggelund Hansen Date: Sun, 30 Sep 2018 23:01:47 +0200 Subject: [PATCH 3/8] Return non-empty list. --- src/List/Extra.elm | 16 ++++++++-------- tests/Tests.elm | 30 +++++++++++++++--------------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/List/Extra.elm b/src/List/Extra.elm index 02bbe1c..f912c36 100644 --- a/src/List/Extra.elm +++ b/src/List/Extra.elm @@ -1679,9 +1679,9 @@ greedyGroupsOfWithStep size step xs = {-| Group equal elements together. This is different from `group` as each sublist will contain *all* equal elements of the original list. - gatherEquals [1,2,1,3,2] == [[1,1],[2,2],[3]] + gatherEquals [1,2,1,3,2] == [(1,[1]),(2,[2]),(3,[])] -} -gatherEquals : List a -> List (List a) +gatherEquals : List a -> List (a, List a) gatherEquals list = gatherEqualsWith (==) list @@ -1689,21 +1689,21 @@ gatherEquals 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. - gatherEqualsBy .name [{age=25},{age=23},{age=25}] == [[{age=25},{age=25}],[{age=23}]] + gatherEqualsBy .name [{age=25},{age=23},{age=25}] == [({age=25},[{age=25}]),({age=23},[])] -} -gatherEqualsBy : (a -> b) -> List a -> List (List a) +gatherEqualsBy : (a -> b) -> List a -> List (a, List a) gatherEqualsBy extract list = gatherEqualsWith (\a b -> (extract a) == (extract b)) list {-| Group equal elements together using a custom equality function. - gatherEquals (==) [1,2,1,3,2] == [[1,1],[2,2],[3]] + gatherEquals (==) [1,2,1,3,2] == [(1,[1]),(2,[2]),(3,[])] -} -gatherEqualsWith : (a -> a -> Bool) -> List a -> List (List a) +gatherEqualsWith : (a -> a -> Bool) -> List a -> List (a, List a) gatherEqualsWith testFn list = let - helper : List a -> List (List a) -> List (List a) + helper : List a -> List (a,List a) -> List (a, List a) helper scattered gathered = case scattered of [] -> @@ -1714,6 +1714,6 @@ gatherEqualsWith testFn list = ( gathering, remaining ) = List.partition (testFn toGather) population in - helper remaining <| (toGather :: gathering) :: gathered + helper remaining <| (toGather, gathering) :: gathered in helper list [] diff --git a/tests/Tests.elm b/tests/Tests.elm index 6dc40b3..46b3d78 100644 --- a/tests/Tests.elm +++ b/tests/Tests.elm @@ -693,15 +693,15 @@ all = , test "single element" <| \() -> gatherEquals [ 1 ] - |> Expect.equal [ [ 1 ] ] + |> Expect.equal [ (1, []) ] , test "proper test" <| \() -> gatherEquals [ 1, 2, 1, 2, 3, 4, 1 ] |> Expect.equal - [ [ 1, 1, 1 ] - , [ 2, 2 ] - , [ 3 ] - , [ 4 ] + [ ( 1, [ 1, 1 ]) + , ( 2, [ 2 ]) + , ( 3, []) + , ( 4, []) ] ] , describe "gatherEqualsBy" @@ -712,15 +712,15 @@ all = , test "single element" <| \() -> gatherEqualsBy identity [ 1 ] - |> Expect.equal [ [ 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 ] + [ ( 1, [ 1, 1 ]) + , ( 2, [ 2 ]) + , ( 3, []) + , ( 4, []) ] ] , describe "gatherEqualsWith" @@ -731,15 +731,15 @@ all = , test "single element" <| \() -> gatherEqualsWith (==) [ 1 ] - |> Expect.equal [ [ 1 ] ] + |> Expect.equal [ (1, []) ] , test "proper test" <| \() -> gatherEqualsWith (==) [ 1, 2, 1, 2, 3, 4, 1 ] |> Expect.equal - [ [ 1, 1, 1 ] - , [ 2, 2 ] - , [ 3 ] - , [ 4 ] + [ ( 1, [ 1, 1 ]) + , ( 2, [ 2 ]) + , ( 3, []) + , ( 4, []) ] ] ] From c3a8a028714bb4fee64d747316a054ad3aa89521 Mon Sep 17 00:00:00 2001 From: Robin Heggelund Hansen Date: Tue, 2 Oct 2018 23:20:48 +0200 Subject: [PATCH 4/8] gatherEqualsWith => gatherWith. --- src/List/Extra.elm | 12 ++++++------ tests/Tests.elm | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/List/Extra.elm b/src/List/Extra.elm index f912c36..8bca6c3 100644 --- a/src/List/Extra.elm +++ b/src/List/Extra.elm @@ -20,7 +20,7 @@ module List.Extra , foldr1 , gatherEquals , gatherEqualsBy - , gatherEqualsWith + , gatherWith , getAt , greedyGroupsOf , greedyGroupsOfWithStep @@ -1683,7 +1683,7 @@ will contain *all* equal elements of the original list. -} gatherEquals : List a -> List (a, List a) gatherEquals list = - gatherEqualsWith (==) list + gatherWith (==) list {-| Group equal elements together. A function is applied to each element of the list @@ -1693,15 +1693,15 @@ and then the equality check is performed against the results of that function ev -} gatherEqualsBy : (a -> b) -> List a -> List (a, List a) gatherEqualsBy extract list = - gatherEqualsWith (\a b -> (extract a) == (extract b)) list + gatherWith (\a b -> (extract a) == (extract b)) list {-| Group equal elements together using a custom equality function. - gatherEquals (==) [1,2,1,3,2] == [(1,[1]),(2,[2]),(3,[])] + gatherWith (==) [1,2,1,3,2] == [(1,[1]),(2,[2]),(3,[])] -} -gatherEqualsWith : (a -> a -> Bool) -> List a -> List (a, List a) -gatherEqualsWith testFn list = +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 = diff --git a/tests/Tests.elm b/tests/Tests.elm index 46b3d78..83bad75 100644 --- a/tests/Tests.elm +++ b/tests/Tests.elm @@ -723,18 +723,18 @@ all = , ( 4, []) ] ] - , describe "gatherEqualsWith" + , describe "gatherWith" [ test "empty list" <| \() -> - gatherEqualsWith (==) [] + gatherWith (==) [] |> Expect.equal [] , test "single element" <| \() -> - gatherEqualsWith (==) [ 1 ] + gatherWith (==) [ 1 ] |> Expect.equal [ (1, []) ] , test "proper test" <| \() -> - gatherEqualsWith (==) [ 1, 2, 1, 2, 3, 4, 1 ] + gatherWith (==) [ 1, 2, 1, 2, 3, 4, 1 ] |> Expect.equal [ ( 1, [ 1, 1 ]) , ( 2, [ 2 ]) From d4ed53fde3c14a3b44b165a317c3dc2fade0f13d Mon Sep 17 00:00:00 2001 From: Robin Heggelund Hansen Date: Tue, 2 Oct 2018 23:21:27 +0200 Subject: [PATCH 5/8] Fixed documentation. --- src/List/Extra.elm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/List/Extra.elm b/src/List/Extra.elm index 8bca6c3..2d10c86 100644 --- a/src/List/Extra.elm +++ b/src/List/Extra.elm @@ -1689,7 +1689,7 @@ gatherEquals 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. - gatherEqualsBy .name [{age=25},{age=23},{age=25}] == [({age=25},[{age=25}]),({age=23},[])] + 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 = From 4f0876872799c60ec01c6e97751da4eefa82deaf Mon Sep 17 00:00:00 2001 From: Robin Heggelund Hansen Date: Thu, 4 Oct 2018 07:10:04 +0200 Subject: [PATCH 6/8] Added gatherEqualsBy and gatherWith to @docs. --- src/List/Extra.elm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/List/Extra.elm b/src/List/Extra.elm index 2d10c86..fed0c4d 100644 --- a/src/List/Extra.elm +++ b/src/List/Extra.elm @@ -112,7 +112,7 @@ module List.Extra # Sublists -@docs splitAt, splitWhen, takeWhileRight, dropWhileRight, span, break, stripPrefix, group, groupWhile, inits, tails, select, selectSplit, gatherEquals +@docs splitAt, splitWhen, takeWhileRight, dropWhileRight, span, break, stripPrefix, group, groupWhile, inits, tails, select, selectSplit, gatherEquals, gatherEqualsBy, gatherWith # Predicates From 58294fda8bc96be9c43b34b67fda880c1a015b39 Mon Sep 17 00:00:00 2001 From: Robin Heggelund Hansen Date: Thu, 4 Oct 2018 07:16:29 +0200 Subject: [PATCH 7/8] Added information about element ordering. --- src/List/Extra.elm | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/List/Extra.elm b/src/List/Extra.elm index fed0c4d..98a5a63 100644 --- a/src/List/Extra.elm +++ b/src/List/Extra.elm @@ -1677,7 +1677,9 @@ greedyGroupsOfWithStep size step xs = [] {-| Group equal elements together. This is different from `group` as each sublist -will contain *all* equal elements of the original list. +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,[])] -} @@ -1688,6 +1690,8 @@ gatherEquals 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},[])] -} @@ -1696,7 +1700,9 @@ gatherEqualsBy extract list = gatherWith (\a b -> (extract a) == (extract b)) list -{-| Group equal elements together using a custom equality function. +{-| 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,[])] -} From 683ce87425e2899b926ca190b1b934c43d838e0f Mon Sep 17 00:00:00 2001 From: Chadtech Date: Mon, 8 Oct 2018 14:52:27 +0200 Subject: [PATCH 8/8] Format gather examples for elm-verify-examples --- src/List/Extra.elm | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/List/Extra.elm b/src/List/Extra.elm index fdec655..bf0a9cc 100644 --- a/src/List/Extra.elm +++ b/src/List/Extra.elm @@ -1863,7 +1863,8 @@ 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 [1,2,1,3,2] + --> [(1,[1]),(2,[2]),(3,[])] -} gatherEquals : List a -> List (a, List a) gatherEquals list = @@ -1875,7 +1876,8 @@ and then the equality check is performed against the results of that function ev 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 .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 = @@ -1886,7 +1888,8 @@ gatherEqualsBy extract list = 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 (==) [1,2,1,3,2] + --> [(1,[1]),(2,[2]),(3,[])] -} gatherWith : (a -> a -> Bool) -> List a -> List (a, List a) gatherWith testFn list =