List Haskell中是否有类似于';唯一的';?
我需要一个可以调用List Haskell中是否有类似于';唯一的';?,list,haskell,unique,List,Haskell,Unique,我需要一个可以调用uniqueBy的函数,该函数将删除元组列表中具有相同snd值的所有元素,而不会像nubBy那样保留其中一个元素。 比如说, uniqueBy [(1,1),(2,1)] 应返回[],而 uniqueBy [(1,1),(1,1),(1,2)] 将返回[(1,2)] 遗憾的是,这个函数uniqueBy不存在,我似乎找不到替代函数或自己实现它的方法,尽管我确信必须有一个简单的方法。有一个函数。因此,您可以这样使用: import Data.Function(on) impor
uniqueBy
的函数,该函数将删除元组列表中具有相同snd
值的所有元素,而不会像nubBy
那样保留其中一个元素。
比如说,
uniqueBy [(1,1),(2,1)]
应返回[]
,而
uniqueBy [(1,1),(1,1),(1,2)]
将返回[(1,2)]
遗憾的是,这个函数uniqueBy不存在,我似乎找不到替代函数或自己实现它的方法,尽管我确信必须有一个简单的方法。有一个函数。因此,您可以这样使用:
import Data.Function(on)
import Data.List(nubBy)
uniqueOnSnd :: Eq b => [(a, b)] -> [(a, b)]
uniqueOnSnd = nubBy ((==) `on` snd)
例如:
Main> uniqueOnSnd [(4,1), (5,2), (3,1), (2,0)]
[(4,1),(5,2),(2,0)]
nubBy
需要时间,就像nub
,O(n2)时间一样。因此,如果您可以对元素进行排序,则更有效的做法是先进行排序,然后执行唯一性过滤器,如:
import Data.Function(on)
import Data.List(sortBy)
nubOrderBy :: (a -> a -> Ordering) -> [a] -> [a]
nubOrderBy cmp = go . sortBy cmp
where go (x1:xs) = x1 : go (dropWhile ((EQ ==) . cmp x1) xs)
go [] = []
uniqueOnSnd :: Ord b => [(a, b)] -> [(a, b)]
uniqueOrdOnSnd = nubOrderBy (compare `on` snd)
这样做的一个缺点是,它不能处理无限列表,而且不会保留顺序,但在这里,w会过滤掉O(n log n)中的重复项。来自
容器的具有保留元素原始顺序的优点。@sjakobi:是的,这使用了集合。我想提供一个不使用其他包中的数据结构的解决方案。当然,我们可以自己实现一个(树)集合,并确实提高成员检查。这也适用于无限列表,因为您只需使用集合
,并在枚举列表时更新它。OP希望删除所有重复项,结果中不留一个。OP已经在标题中提到nubBy,并说他们想要其他内容。这不是简单的库函数应用程序。虽然它不是超级复杂,但您需要自己做一些逻辑。是否应该uniqueBy[(1,1),(2,1)]
返回[(1,1)]
或[]
?打个比方,它是前者,但从你的描述来看,它是后者。它是哪一个?@WillNess它应该返回[],但下面的答案并没有这样做。它将返回第一个。也许你应该编辑你的问题并进行澄清。一种方法是通过排序
,然后分组方式
,然后筛选
和映射
来运行列表,以仅保留包含多个元素的组,并将生成的组分别转换为头元素的snd
字段。现在,您有了一个snd
值的列表来去除元组,因此可以对原始列表进行另一个filter
,在谓词中使用elem
。