如何将等级分配给Haskell中的元组列表(考虑到联系)?理想情况下,想要一个给定元组列表的函数将返回具有等级的元组列表。
样本输入(假设基于每个元组的snd以升序排列):
results1 = [("a",12),("b",56),("c",61),("d",73),("e",75),("f",75),("g",81),("h",82),("i",91),("j",97)]
样本输出:
[("a",1),("b",2),("c",3),("d",4),("e",5.5),("f",5.5),("g",7),("h",8),("i",9),("j",10)]
注意,“e”和“f”并列,因此它们的等级(5和6)加在一起并除以2。更普遍的是,特定等级范围[i..j]的任何n个领带都会全部收到相同的总和[i..j]/n。
注意:我今天才开始学习Haskell(来自Python和Java),所以我希望提供有用的提示而不是给出答案。足以将我推向正确的解决方案。谢谢!
编辑/部分2问题:好,所以感谢jamshidh,chunksof50和leftaround关于我想出了
sortStudents xs = sortBy (compare `on` snd) xs
prerankStudents xs = groupBy ((==) `on` (snd.fst)) (zip (sortStudents xs) [1..])
rankStudents xs = concat [ [if length ys > 1 then (a, fromIntegral (sum (map snd ys)) / fromIntegral (length ys)) else (a,fromIntegral c) | ((a,b),c) <- ys] | ys <- (prerankStudents . sortStudents) xs ]
我对sortStudents和prerankStudents相对满意,但是rankStudents有点像我在重新编写python(列表理解),尽管我不确定在这种情况下是好是坏。我尝试用case..of递归地实现rankStudents,但是消除错误似乎在我头上。如果有人愿意向我详细解释为什么它不起作用,请使用以下代码。
rankStudents xs = let ss = prerankStudents xs
rankStudents' ys = case ys of [] -> []
[((a,b),c)] -> [(a,c)]
(((a1,b1),c1):zs) -> [((fst.fst) tup, fromIntegral (sum (map snd ys)) / fromIntegral (length ys)) | tup <- ys]
y:ys -> rankStudents' y ++ rankStudents' ys
in rankStudents' ss
最佳答案
以下是一些有用的功能。...
Data.List.groupBy
Data.List.sortBy --you won't actually need this if you assume the input is ordered, but I threw it in anyway
Data.Function.on
(==)
您可以按第二项对数据进行分组,然后使用递归输出值,增加每个项目的排名...。如果组中的项目数大于一,则只需增加此值,然后使用根据组中的等级的值的平均值。
这足以让您继续前进而没有给出完整的答案。
关于haskell - 将等级分配给haskell中的元组列表,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20915168/