好吧,这可能会出现在前奏中,但是:有没有标准的库函数来查找列表中的唯一元素?我的(重新)实施,澄清,是:
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)
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)
事实上,已经提出添加nubOrd
到Data.Set
.
dpa*_*tru 10
import Data.Set (toList, fromList)
uniquify lst = toList $ fromList lst
Run Code Online (Sandbox Code Playgroud)