haskell列表中的独特元素

muh*_*ten 50 haskell list

好吧,这可能会出现在前奏中,但是:有没有标准的库函数来查找列表中的唯一元素?我的(重新)实施,澄清,是:

has :: (Eq a) => [a] -> a -> Bool
has [] _ = False
has (x:xs) a
  | x == a    = True
  | otherwise = has xs a

unique :: (Eq a) => [a] -> [a]
unique [] = []
unique (x:xs)
  | has xs x  = unique xs
  | otherwise = x : unique xs
Run Code Online (Sandbox Code Playgroud)

Art*_*ius 92

我搜索(Eq a) => [a] -> [a]Hoogle.

第一个结果是nub(从列表中删除重复的元素).

Hoogle很棒.

  • 另外,您可以提供自己的相等函数,如下所示: nubBy :: (a -> a -> Bool) -> [a] -> [a] (2认同)
  • 值得一提的是``nub`函数来自`Data.List`包. (2认同)

Yit*_*itz 50

nub从功能Data.List(不,它实际上不是在前奏)绝对不会像你想要什么,但它并不像你完全一样unique的功能.它们都保留元素的原始顺序,但unique保留每个元素的最后一个出现,同时nub保留第一个出现的元素.

如果这很重要(尽管我感觉不是这样),你可以这样做,使nub行为完全一样unique:

unique = reverse . nub . reverse
Run Code Online (Sandbox Code Playgroud)

此外,nub仅适用于小型列表.它的复杂性是二次的,所以如果你的列表可以包含数百个元素,它会开始变慢.

如果将类型限制为具有Ord实例的类型,则可以使其更好地扩展.这种变化nub仍然保留了列表元素的顺序,但其复杂性为O(n * log n):

import qualified Data.Set as Set

nubOrd :: Ord a => [a] -> [a] 
nubOrd xs = go Set.empty xs where
  go s (x:xs)
   | x `Set.member` s = go s xs
   | otherwise        = x : go (Set.insert x s) xs
  go _ _              = []
Run Code Online (Sandbox Code Playgroud)

事实上,已经提出添加nubOrdData.Set.


dpa*_*tru 10

import Data.Set (toList, fromList)
uniquify lst = toList $ fromList lst
Run Code Online (Sandbox Code Playgroud)

  • 这会改变元素的顺序. (4认同)