Reputation:
I have a list, say [1,2,3,4,3,2,4]
.
I would like to output every element once, for example [1,2,3,4]
.
How can I do this in Haskell?
Upvotes: 4
Views: 2933
Reputation: 26191
Basically since sort
ing in Haskell lists are quite fast (best case O(n) worst case O(nlogn) we might use sorting first and then folding for an efficient solution with an additional effect of getting a sorted result, if that would be beneficial.
The following code is for minimal cons
operations;
Prelude Data.List
λ> :{
λ| foldr (\e rs -> case rs of
λ| [] -> [e]
λ| (x:xs) -> if x == e then rs else e:rs) [] $ sort [8,8,4,3,2,3,3,2,1,8,3,5]
λ| :}
[1,2,3,4,5,8]
and the following is, as per pointed out by @Joseph Sible-Reinstate Monica for enhanced laziness.
Prelude Data.List
λ> :{
λ| foldr (\e rs -> e : case rs of
λ| [] -> []
λ| (x:xs) -> if x == e then xs else rs) [] $ sort [8,8,4,3,2,3,3,2,1,8,3,5]
λ| :}
[1,2,3,4,5,8]
Upvotes: 2
Reputation: 111
You can do it with sets using Data.set:
import qualified Data.Set as Set
lst = [1,2,3,4,1,2,3]
y = Set.fromList lst
The output is:
y
=> fromList [1,2,3,4]
Upvotes: 11
Reputation: 1375
There is a nub
function exactly for that. However, it has complexity of O(n^2), which is not so good. In case of numbers (or any Ord
type) you can make your own unique
function like this:
unique :: Ord a => [a] -> [a]
unique = map head . group . sort
You'll need to import Data.List
.
It acts like this:
sort [1,2,3,1,2] -> [1,1,2,2,3] -- to order the elements
group [1,1,2,2,3] -> [[1,1],[2,2],[3]] -- to group equal ones
map head [[1,1],[2,2],[3]] -> [1,2,3] -- to take first of groups
That has complexity of O(n log n), which is a way better.
Upvotes: 5
Reputation: 477210
You can make use of nub :: Eq a => [a] -> [a]
which acts as a uniqness filter. It will however require O(n2) since it does not use a data structure like a hashset.
For example:
Prelude Data.List> nub [1,2,3,4,3,2,4]
[1,2,3,4]
If the elements are of a type that is a member of the Hashable
typeclass, you can use for example hashNub :: (Eq a, Hashable a) => [a] -> [a]
to perform a uniqness filter in O(n log n):
Prelude ClassyPrelude> hashNub [1,2,3,4,3,2,4]
[1,2,3,4]
Upvotes: 11