Haskell中如何按子列表元素和对列表的子列表进行排序?
按子列表元素和排序Haskell列表的实现
要实现按每个子列表的元素和升序排序整数列表的列表,Haskell里有非常简洁的实现方式,核心是利用自定义排序规则结合子列表求和逻辑,下面一步步拆解:
核心实现代码
首先,我们可以借助Data.List中的sortBy(用于自定义排序规则)和Data.Ord中的comparing(将普通函数转换为比较函数)来快速完成:
import Data.List (sortBy) import Data.Ord (comparing) -- 按子列表元素和升序排序 sortBySum :: [[Int]] -> [[Int]] sortBySum = sortBy (comparing sum)
代码解释
sum函数:Haskell标准库自带的函数,用于计算数字列表的元素和,比如sum [5,3]会返回8,sum [1,1,1,1]返回4。comparing sum:comparing是一个工具函数,它接受一个映射函数(这里是sum),返回一个用于比较两个值的函数——具体来说,它会把两个子列表分别传入sum,然后比较它们的和大小。sortBy:接受一个比较函数和待排序列表,按照比较函数的规则对列表进行稳定排序(和相同的子列表会保留原输入中的相对顺序)。
测试示例
用你给出的输入测试:
sortBySum [[5,3],[1,1,1,1],[2],[10,22,0]]
输出结果正好是:
[[2],[1,1,1,1],[5,3],[10,22,0]]
手动实现比较函数(可选)
如果你不想使用comparing,也可以手动写出比较逻辑,效果完全一致:
import Data.List (sortBy) sortBySum' :: [[Int]] -> [[Int]] sortBySum' = sortBy (\a b -> compare (sum a) (sum b))
这里的匿名函数\a b -> compare (sum a) (sum b)直接定义了两个子列表的比较规则:先计算各自的和,再用compare函数比较和的大小(compare会返回LT/EQ/GT,对应升序排序的规则)。
注意事项
- 确保导入对应的模块:
sortBy在Data.List中,comparing在Data.Ord中;如果不想导入,也可以使用全限定名称,比如Data.List.sortBy和Data.Ord.comparing,但导入模块会让代码更简洁。 - 稳定排序特性:如果两个子列表的元素和相同,
sortBy会保留它们在原输入中的相对位置,这是Haskell中基于归并排序的sortBy的默认特性。
内容的提问来源于stack exchange,提问作者John Seed
相关产品推荐
相关产品推荐

