首页 > 解决方案 > 使用 sortBy 对列表进行排序

问题描述

我正在尝试根据每个元组中的第 4 个元素对我的元组列表进行排序。第四个元素包含一个人名字符串。我想将包含相同名称的元组放在一起。排序前的元组列表示例如下:

[("A",100,"Q",3,"Todd",2.0),
 ("B",203,"R",3,"Rachel",1.66),
 ("B",273,"F",1,"Mike",2.66),
 ("A",200,"P",1,"Rachel",0.0),
 ("A",549,"D",3,"Todd",2.0),
 ("B",220,"S",3,"Todd",4.0),
 ("B",101,"M",3,"Jon",3.33),
 ("A",999,"N",3,"Rachel",1.33)]

我也希望它看起来像:

[("A",100,"Q",3,"Todd",2.0),
 ("A",549,"D",3,"Todd",2.0),
 ("B",220,"S",3,"Todd",4.0),
 ("B",203,"R",3,"Rachel",1.66),
 ("A",200,"P",1,"Rachel",0.0),
 ("A",999,"N",3,"Rachel",1.33),
 ("B",273,"F",1,"Mike",2.66),
 ("B",101,"M",3,"Jon",3.33)]

我需要的是让所有包含 Todd 的元组彼此相邻,依此类推。名称出现的顺序无关紧要,只是它们彼此相邻。

sortedList= show . sortBy byName . (map stringToTuple) . (map words) . lines

这是我调用排序依据的代码行。我知道我需要创建一个函数byName,以某种方式确定元组是否共享一个通用名称。

任何帮助引导我进入编写该byName方法的正确方向将不胜感激。谢谢

标签: haskell

解决方案


从以下类型开始sortBy

> :t sortBy
sortBy :: (a -> a -> Ordering) -> [a] -> [a]

这意味着byName需要有 type a -> a -> Ordering。在这种情况下,a是一个元组,其第五个元素为 type StringbyName将忽略其他字段。所以你需要定义一个函数

type MyType = (String, Int, String, Int, String, Double)
byName :: MyType -> MyType -> Ordering
byName (_, _, _, _, a, _) (_, _, _, _, b, _) = ...

我把用...正确的表达式替换为练习。

(回想一下,这Ordering是一个具有三个值的类型LTEQ, 和GT, 其中byName a b == LTif a < b, byName a b == EQifa == bbyName a b == GTif a > b。在您的情况下,两个元组将比较相等,只要它们具有相同的名称。听起来您实际上并不关心无论是byName退货LT还是GT其他。)


推荐阅读