2011-11-29 59 views
1

我来自Python和Java背景,所以Haskell对我来说是完全不同的。我正在尝试一些活动来学习,但我坚持这一点。haskell元组列表,带有唯一元组

我有一个元组的有序列表,[(name,studentNumber)],我想过滤这个列表,以便每个学生和每个s​​tudentNumber只出现一次。由于元组是有序的,我想保留名字或学号的第一个实例并删除可能出现的其他元素。

我试着做一个列表comphrenshion,但我不知道如何检查名称或编号是否已被添加到列表中。

+0

最简单的解决办法是'nub',但因为它可以不依赖于名单上被排序(你的意思了吧?列表是总是有序的,所以明确说明是没有意义的),它会(除非我大错特错)比根据这种条件量身定做的东西少一点效率。 – delnan

+0

如果这是输入,应该输出什么? '[(“Anne”,3),(“Anne”,5),(“Bob”,5)]' – dave4420

+0

我的意思是命令这样的第一个元组意味着他们是第一个注册的学生,第二个元组是第二个元组学生等。我需要保留这个命令! – matthieu

回答

5

听起来好像你想要的(作为第一,效率低下的近似值)是这样的:

import Data.List (nubBy) 
import Data.Function (on) 

filt = nubBy ((==) `on` snd) . nubBy ((==) `on` fst) 

nubBy第一次调用将导致在每个名字只出现一次的列表,然后传递给第二个,产生一个列表,其中每个数字只出现一次。

仅使用nub将产生一个列表,其中每个(name,number)对只出现一次;可能仍会有不同名称的不同号码和号码的重复名称。

(当然,定制的东西与蓄能会更快。)

+0

谢谢!我在另一篇SO文章中发现了nubBy,但没有足够的想法去做!这很好,谢谢! – matthieu

0

为了使用独特的列表,前奏中总是会有nub函数,我认为它应该完全符合您的需求!

+3

'nub '来自'Data.List' –

+0

哎呀,没错! –

+0

[永远不要使用'nub'函数。](https://github.com/nh2/haskell-ordnub#dont-use-nub)它是二次的。 – nh2

1

可以窥探Data.Listsources,写你的扩展nub功能:

type Student = (Name, Number) 
type Name = String 
type Number = Int 

unique :: [Student] -> [Student] 
unique = go [] [] 
    where 
    go unames unumbers ([email protected](name, number):ss) 
     | name `elem` unames || number `elem` unumbers = go unames unumbers ss 
     | otherwise = s : go (name:unames) (number:unumbers) ss 
    go _ _ [] = [] 

应该做你想要什么。