@@ -92,6 +92,7 @@ module Data.Array
9292 , nub
9393 , nubEq
9494 , nubBy
95+ , nubByEq
9596 , union
9697 , unionBy
9798 , delete
@@ -879,41 +880,55 @@ groupBy op xs =
879880-- | ```
880881-- |
881882nub :: forall a . Ord a => Array a -> Array a
882- nub arr = case head indexedAndSorted of
883- Nothing -> []
884- Just x -> map fst $ sortWith snd $ pureST do
885- -- TODO: use NonEmptyArrays here to avoid partial functions
886- result <- unsafeThaw $ singleton x
887- foreachE indexedAndSorted \pair@(Tuple x' i) -> do
888- lst <- fst <<< unsafePartial (fromJust <<< last) <$> unsafeFreeze result
889- when (lst /= x') $ void $ pushSTArray result pair
890- unsafeFreeze result
891-
892- where
893- indexedAndSorted = sort $ mapWithIndex (flip Tuple ) arr
883+ nub = nubBy compare
894884
895885-- | Remove the duplicates from an array, creating a new array.
896886-- |
897887-- | This less efficient version of `nub` only requires an `Eq` instance.
898888-- |
899889-- | ```purescript
900- -- | nub [1, 2, 1, 3, 3] = [1, 2, 3]
890+ -- | nubEq [1, 2, 1, 3, 3] = [1, 2, 3]
901891-- | ```
902892-- |
903893nubEq :: forall a . Eq a => Array a -> Array a
904- nubEq = nubBy eq
894+ nubEq = nubByEq eq
895+
896+ -- | Remove the duplicates from an array, where element equality is determined
897+ -- | by the specified ordering, creating a new array.
898+ -- |
899+ -- | ```purescript
900+ -- | nubBy compare [1, 3, 4, 2, 2, 1] == [1, 3, 4, 2]
901+ -- | ```
902+ -- |
903+ nubBy :: forall a . (a -> a -> Ordering ) -> Array a -> Array a
904+ nubBy comp xs = case head indexedAndSorted of
905+ Nothing -> []
906+ Just x -> map snd $ sortWith fst $ pureST do
907+ -- TODO: use NonEmptyArrays here to avoid partial functions
908+ result <- unsafeThaw $ singleton x
909+ foreachE indexedAndSorted \pair@(Tuple i x') -> do
910+ lst <- snd <<< unsafePartial (fromJust <<< last) <$> unsafeFreeze result
911+ when (comp lst x' /= EQ ) $ void $ pushSTArray result pair
912+ unsafeFreeze result
913+ where
914+ indexedAndSorted :: Array (Tuple Int a )
915+ indexedAndSorted = sortBy (\x y -> comp (snd x) (snd y))
916+ (mapWithIndex Tuple xs)
905917
906918-- | Remove the duplicates from an array, where element equality is determined
907919-- | by the specified equivalence relation, creating a new array.
908920-- |
921+ -- | This less efficient version of `nubBy` only requires an equivalence
922+ -- | relation.
923+ -- |
909924-- | ```purescript
910- -- | nubBy (\a b -> a `mod` 3 == b `mod` 3) [1, 3, 4, 5, 6] = [1,3,5]
925+ -- | nubByEq (\a b -> a `mod` 3 == b `mod` 3) [1, 3, 4, 5, 6] = [1,3,5]
911926-- | ```
912927-- |
913- nubBy :: forall a . (a -> a -> Boolean ) -> Array a -> Array a
914- nubBy eq xs =
928+ nubByEq :: forall a . (a -> a -> Boolean ) -> Array a -> Array a
929+ nubByEq eq xs =
915930 case uncons xs of
916- Just o -> o.head : nubBy eq (filter (\y -> not (o.head `eq` y)) o.tail)
931+ Just o -> o.head : nubByEq eq (filter (\y -> not (o.head `eq` y)) o.tail)
917932 Nothing -> []
918933
919934-- | Calculate the union of two arrays. Note that duplicates in the first array
@@ -938,7 +953,7 @@ union = unionBy (==)
938953-- | ```
939954-- |
940955unionBy :: forall a . (a -> a -> Boolean ) -> Array a -> Array a -> Array a
941- unionBy eq xs ys = xs <> foldl (flip (deleteBy eq)) (nubBy eq ys) xs
956+ unionBy eq xs ys = xs <> foldl (flip (deleteBy eq)) (nubByEq eq ys) xs
942957
943958-- | Delete the first element of an array which is equal to the specified value,
944959-- | creating a new array.
0 commit comments