我的 remStudentdup 功能有问题。我希望它从列表中提取并删除所有多余的学生,然后返回整个列表而不重复学生。我会修改它吗?
import Data.List
type CourseData = [(String,String,String,String,String)]
l :: CourseData
--list contains name of student, year, programme and personal tutor
l = [("fondi","201202378","2012","Bsc280","mr tautology"),
("fondi","201202378","2012","Bsc280","mr tautology"),
("Sylvee","200801245","2008","Bsc209","ms puma"),
("dijeje","201307845","2013","Bsc205","mr tautology"),
("heron","201002567","2010","Bsc280","mr setlhako"),
("slow","201198746","2011","Bsc205","mr mampu"),
("Sylvee","201198746","2008","bsc209","ms puma"),
("Sylvee","201198746","2008","bsc209","ms puma")]
rmdups :: Eq a => [a] -> [a]
rmdups [] = []
rmdups (x:xs) | x `elem` xs = rmdups xs
| otherwise = x : rmdups xs
remStudentdup :: CourseData -> [String]
remStudentdup list =rmdups [name|(name,id,yr,prog,ptut)<-list]
remStudentdup 函数只返回名称,但我希望它返回所有字段
答案 0 :(得分:1)
好吧,让它返回所有字段:
remStudentdup :: CourseData -> CourseData
remStudentdup = rmdups
你可以摆脱remStudentdup
函数,因为它只是将调用的参数传递给rmdups
函数,而是使用rmdups
。
答案 1 :(得分:0)
您的列表理解[name|(name,id,yr,prog,ptut)<-list]
返回仅包含名称的列表,因此rmdups
除了名称之外永远不会看到任何其他内容。
一种可能的解决方案是将完整列表传递给rmdups并稍后提取名称:
rmdups :: Eq a => [a] -> [a]
rmdups [] = []
rmdups (x:xs) | x `elem` xs = rmdups xs
| otherwise = x : rmdups xs
remStudentdup :: CourseData -> [String]
remStudentdup list = rmdups list
但是,这会比较学生记录的记录,如果所有字段都相同,则两条记录相同。一个更好的解决方案是通过将比较函数传递给它来使rmdups
更通用:
elemBy :: (a -> a -> Bool) -> a -> [a] -> Bool
elemBy isEqual x (y:ys) = isEqual x y || elemBy isEqual x ys
elemBy _ _ [] = False
rmdups' :: (a -> a -> Bool) -> [a] -> [a]
rmdups' _ [] = []
rmdups' isEqual (x:xs) | elemBy isEqual x xs = rmdups xs
| otherwise = x : rmdups xs
studentName (name,_id,_yr,_prog,_ptut) = name
remStudentdup :: CourseData -> [String]
remStudentdup list = rmdups' (\s1 s2 -> studentName s1 == studentName s2) list