2020-02-13 20:38:23 +03:00
|
|
|
module Data.List.Extended
|
|
|
|
( duplicates
|
2020-05-27 18:02:58 +03:00
|
|
|
, uniques
|
2020-12-21 12:11:37 +03:00
|
|
|
, getDifference
|
2021-05-27 18:06:13 +03:00
|
|
|
, getDifferenceOn
|
|
|
|
, getOverlapWith
|
2021-07-30 14:33:06 +03:00
|
|
|
, hasNoDuplicates
|
2020-02-13 20:38:23 +03:00
|
|
|
, module L
|
|
|
|
) where
|
|
|
|
|
2021-05-27 18:06:13 +03:00
|
|
|
import Data.Function (on)
|
|
|
|
import Data.Hashable (Hashable)
|
2020-02-13 20:38:23 +03:00
|
|
|
import Prelude
|
|
|
|
|
2021-05-27 18:06:13 +03:00
|
|
|
import qualified Data.HashMap.Strict.Extended as Map
|
|
|
|
import qualified Data.HashSet as Set
|
|
|
|
import qualified Data.List as L
|
|
|
|
import qualified Data.List.NonEmpty as NE
|
2020-02-13 20:38:23 +03:00
|
|
|
|
|
|
|
duplicates :: (Eq a, Hashable a) => [a] -> Set.HashSet a
|
|
|
|
duplicates =
|
|
|
|
Set.fromList . Map.keys . Map.filter (> 1) . Map.fromListWith (+) . map (,1::Int)
|
2020-05-27 18:02:58 +03:00
|
|
|
|
|
|
|
uniques :: Eq a => [a] -> [a]
|
|
|
|
uniques = map NE.head . NE.group
|
2020-12-21 12:11:37 +03:00
|
|
|
|
|
|
|
getDifference :: (Eq a, Hashable a) => [a] -> [a] -> Set.HashSet a
|
|
|
|
getDifference = Set.difference `on` Set.fromList
|
2021-05-27 18:06:13 +03:00
|
|
|
|
|
|
|
getDifferenceOn :: (Eq k, Hashable k) => (v -> k) -> [v] -> [v] -> [v]
|
|
|
|
getDifferenceOn f l = Map.elems . Map.differenceOn f l
|
|
|
|
|
|
|
|
getOverlapWith :: (Eq k, Hashable k) => (v -> k) -> [v] -> [v] -> [(v, v)]
|
|
|
|
getOverlapWith getKey left right =
|
|
|
|
Map.elems $ Map.intersectionWith (,) (mkMap left) (mkMap right)
|
|
|
|
where
|
|
|
|
mkMap = Map.fromList . map (\v -> (getKey v, v))
|
2021-07-30 14:33:06 +03:00
|
|
|
|
|
|
|
hasNoDuplicates :: (Eq a, Hashable a) => [a] -> Bool
|
|
|
|
hasNoDuplicates xs = Set.size (Set.fromList xs) == length xs
|