为haskell中的元组列表分配秩

为haskell中的元组列表分配秩,haskell,tuples,rank,Haskell,Tuples,Rank,如何为Haskell中的元组列表分配秩(考虑到关系)?理想情况下,如果想要一个给定元组列表的函数,它将返回一个具有秩的元组列表 样本输入(假设根据每个元组的snd按升序排列): 样本输出: [("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个数量的连接都将接收相同的和

如何为Haskell中的元组列表分配秩(考虑到关系)?理想情况下,如果想要一个给定元组列表的函数,它将返回一个具有秩的元组列表

样本输入(假设根据每个元组的snd按升序排列):

样本输出:

[("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),因此我更愿意提供有用的提示,而不是透露答案。足以让我找到正确的解决方案。谢谢

编辑/第二部分问题:好的,多亏了jamshidh、chunksof50和leftaroundabout,我想出了

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 xs=sortBy(compare`on`snd)xs
prerankStudents xs=groupBy(==)`on`(snd.fst))(zip(sortStudents xs)[1..]

rankStudents xs=concat[[如果长度ys>1,那么(a,from integral(sum(map snd ys))/from integral(length ys)),或者(a,from integral c)|((a,b),c)以下是一些您会发现有用的函数

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
(==)
您可以按第二项对数据进行分组,然后使用递归输出值,增加每个项目的排名…如果组中的项目数大于一,只需增加该值,并根据组中的排名输出值的平均值


这就足够让你在不给出完整答案的情况下继续了。

如果列表操作系统确实已经排序(),那么这或多或少会用一个简单的枚举来替换
snd
字段。所以首先要做枚举!这在Haskell中非常简单:
zip results1[1..]

[(("a",12),1),(("b",56),2),(("c",61),3),(("d",73),4),(("e",75),5),(("f",75),6),(("g",81),7),(("h",82),8),(("i",91),9),(("j",97),10)]
剩下要做的主要是均衡重复项。我首先将它们分组:
groupBy((==)`on`(snd.snd))
gives

[[(("a",12),1)],[(("b",56),2)],[(("c",61),3)],[(("d",73),4)],[(("e",75),5),(("f",75),6)],[(("g",81),7)],[(("h",82),8)],[(("i",91),9)],[(("j",97),10)]]
请注意,除了
“e”
“f”
共享一个列表外,所有元素现在都在一个单例列表中


然后,对这些列表中的每一个进行平均排名。这可以很好地写成一个带有模式匹配的列表理解,这是一个很好的练习。

您要求的提示和技巧,因此这里先介绍一些技巧:

  • 用于查找有关函数的信息
  • 使用类型签名并注意它们
  • 通过使用纯函数式的方法学习haskell,您将学到更多,因此,除了最终管道之外,请避免使用IO monad,否则您将像以前一样完成写作
  • 递归是你的扳手,但高阶函数是你的重型机器
  • 写很多简单的小函数,而不是一个解决问题的大函数
  • 暗示

    • zip
      zipWith
      -组合列表。在某个时刻,您将需要无限列表
      [1..]
    • groupBy
      。当我们在这个领域工作时,在某个时候可以查看一下
    上的函数
    ,但通常情况下,类型签名没有多大帮助,您希望看到示例
    
  • sum
    length
    map
    map
    是一个基本的列表处理函数。
    map
    是一个基本的列表处理函数。使用类型来确定您可以使用
    fst.snd
    snd.fst
    fst.fst
    snd.snd
  • map
    更多,最后你需要
    concat
  • 您可能最终定义了其他功能,或者最终以一种非常不同的方式进行定义,但了解这些功能将培养您的Haskell技能

    [(("a",12),1),(("b",56),2),(("c",61),3),(("d",73),4),(("e",75),5),(("f",75),6),(("g",81),7),(("h",82),8),(("i",91),9),(("j",97),10)]
    
    [[(("a",12),1)],[(("b",56),2)],[(("c",61),3)],[(("d",73),4)],[(("e",75),5),(("f",75),6)],[(("g",81),7)],[(("h",82),8)],[(("i",91),9)],[(("j",97),10)]]