4

假设我有一个类似[[1,3,4],[1,5,6,7],[2,8,0]]or的列表列表["QQQ", "RRRR", "TTTTT"],是否有一个函数可以按内部列表中的元素数量对它们进行排序,即在Int列表中,4 元素列表放在前面,在Strings 列表中,Ts 去到前面,然后是Rs?

4

3 回答 3

5

sortBy与自定义谓词一起使用:

Prelude> import Data.List
Prelude Data.List> let l = [[1,3,4],[1,5,6,7],[2,8,0]]
Prelude Data.List> sortBy (\e1 e2 -> compare (length e2) (length e1))  l
[[1,5,6,7],[1,3,4],[2,8,0]]

编辑:感谢@JJJ 提供更漂亮的变体

Prelude Data.List> import Data.Ord
Prelude Data.List Data.Ord> sortBy (flip $ comparing length) l
[[1,5,6,7],[1,3,4],[2,8,0]]
于 2013-10-25T10:45:59.780 回答
1

sortBy来自 Data.List 和comparing来自 Data.Ord 将为您提供帮助。

foo = sortBy (comparing (negate . length))

bar = foo ["QQQ", "RRRR", "TTTTT"]
于 2013-10-25T10:55:04.587 回答
0

我想添加另一个解决方案来记忆给定列表的长度。否则,每次比较都会重新计算长度,这意味着大型列表的大量开销。

import Control.Arrow ((&&&))
import Data.List (sort, sortBy)
import Data.Ord (comparing)

sortByLen :: [[a]] -> [[a]]
sortByLen = map snd . sortBy (comparing fst) . map ((negate . length) &&& id)

如果您还希望按字典顺序对相同长度的列表进行排序,则可以使用稍微简单的

sortByLen' :: (Ord a) => [[a]] -> [[a]]
sortByLen' = map snd . sort . map ((negate . length) &&& id)
于 2013-10-25T20:02:21.187 回答