Reputation: 109
I come from a Python and Java background so Haskell is quite different for me. I'm trying little activities to learn but I am stuck on this .
I have an ordered list of tuples, [(name, studentNumber)], and I want to filter this list so that each student and each studentNumber appears only once. Since the tuples are ordered, I want to keep the first instance of a name or studentNumber and remove any others that may show up.
I tried doing a list comphrenshion, but I'm not sure how to check if a name or number has already been added to the list.
Upvotes: 2
Views: 1583
Reputation: 2535
It sounds as if you'd want (as a first, inefficient approximation) something like this:
import Data.List (nubBy)
import Data.Function (on)
filt = nubBy ((==) `on` snd) . nubBy ((==) `on` fst)
The first call to nubBy
will result in a list in which each name appears only once, and that will then be passed to the second, resulting in a list in which each number appears only once.
Just using nub
will result in a list in which each (name,number)
pair occurs only once; there might still be repetitions of names with different numbers and numbers with different names.
(Of course something custom with an accumulator would be faster.)
Upvotes: 5
Reputation: 3900
You can spy on Data.List
sources and write your extended nub
function:
type Student = (Name, Number)
type Name = String
type Number = Int
unique :: [Student] -> [Student]
unique = go [] []
where
go unames unumbers (s@(name, number):ss)
| name `elem` unames || number `elem` unumbers = go unames unumbers ss
| otherwise = s : go (name:unames) (number:unumbers) ss
go _ _ [] = []
Should do what you want.
Upvotes: 1
Reputation: 970
To unique-ify a list there's always the nub
function from the prelude, I think that should do exactly what you need!
Upvotes: 0