Elfi
Elfi

Reputation: 63

How to use groupBy on a list of tuples?

How can I group this list by second element of tuples:

[(3,2),(17,2),(50,3),(64,3)]

to get something like:

[[(3,2),(17,2)],[(50,3),(64,3)]]

I'm actually a newcomer to Haskell...and seems to be falling in love with it. Hope you would help me find an efficient way.

Upvotes: 1

Views: 176

Answers (1)

Silvio Mayolo
Silvio Mayolo

Reputation: 70277

It sounds like you've already identified that you want Data.List.groupBy. The type of this function is

groupBy :: (a -> a -> Bool) -> [a] -> [[a]] 

So it takes a binary predicate, i.e. an equivalence relation determining how to group elements. You want to group elements by equality on the second term of a pair, so you want

groupBy (\x y -> snd x == snd y) myList

Where snd is a built-in function that gets the second element of a pair.

Incidentally, this pattern of "apply a function to two arguments and then apply a binary function to the results" is very common, especially when calling Data.List functions, so Data.Function provides on.

on :: (b -> b -> c) -> (a -> b) -> a -> a -> c 

Weird signature, but the use case is just what we want.

((+) `on` f) x y = f x + f y

So your desired groupBy can be written as

groupBy ((==) `on` snd)

Note that groupBy only finds consecutive equal elements. You didn't indicate whether you wanted consecutive equal elements or all equal elements, but if you want the latter, then I don't believe Haskell base provides that function, though you could certainly write it recursively yourself.

Upvotes: 7

Related Questions