Remove duplicate pairs in a list

I am familiar with a function nubin lists containing numbers, characters or strings, but can someone explain to me how I can use the function nubfrom Data.Listthe list of pairs?

Example:

[('a', 3),( 'b', 2),('a', 1),('b', 4)]

to

[('a', 3),('b', 2)]

As you can see, I want to delete all pairs in which the key from the pair (key, value) is already in the list.

+4
source share
4 answers

Here is one way:

Prelude Data.List> nubBy (\(x,_) (x', _) -> x == x') [('a',1),('b',2),('b',3)]
[('a',1),('b',2)]
+8
source

"", , . nub, . "" , . 'seen', , 'seen'.

:

removeDuplicate :: (Eq a) => [(a, b)] -> [(a, b)]
removeDuplicate lst = go lst []
    where go [] seen = seen
          go (x:xs) seen 
              | any (\(a, _) -> a == fst x) seen = go xs seen
              | otherwise = go xs (seen ++ [x])

:

*Main> removeDuplicate [('a', 3),( 'b', 2),('a', 1),('b', 4)]
[('a',3),('b',2)]

foldl:

removeDuplicate' = foldl (\seen x -> if any (\(a, _) -> a == fst x) seen
                                     then seen 
                                     else seen ++ [x]) []

over-kill , sortBy Data.List, groupBy. map(), :

import Data.List
import Data.Function

removeDuplicate'' :: (Ord a) => [(a, b)] -> [(a, b)]
removeDuplicate'' xs = map head $ groupBy ((==) `on` fst) $ sortBy (compare `on` fst) xs

: , nubBy, , .

, on Data.Function, .

+2

In the same vein as RoadRunner's answer, you can implement this seenas Setwell as even wrap it in Statemonad.

module Main where

-- mtl
import Control.Monad.State (State, get, put, evalState)
-- containers
import Data.Set            (Set, empty, insert, member)

removeDuplicates :: Ord a => [(a, b)] -> [(a, b)]
removeDuplicates xs = evalState (go xs) (empty, [])
  where
  go [] = do
    (_, ys) <- get
    return $ reverse ys
  go (x:xs) = do
    (s, ys) <- get
    case member (fst x) s of
      True  -> go xs
      False -> do
        put $ (insert (fst x) s, x:ys)
        go xs

main :: IO ()
main = do
  let testData = [('a', 3),( 'b', 2),('a', 1),('b', 4)]
  print $ removeDuplicates testData

and again, like RoadRunner's answer, use nubByfor this. This method is only interesting as an exercise.

+2
source

I would do the following:

λ:> import Data.List (nubBy)
λ:> import Data.Function (on)
λ:> nubBy ((==) `on` snd) [('a',1),('b',2),('b',3)]
[('a',1),('b',2),('b',3)]
+1
source

Source: https://habr.com/ru/post/1692178/


All Articles