2013-10-25 99 views
2

说如果我有一个列表,例如[[1,3,4],[1,5,6,7],[2,8,0]]["QQQ", "RRRR", "TTTTT"],是否有一个函数会按照内部列表中的元素数排序,即在Int列表中的4元素列表走到前面,在String的列表中,T s到达前面,然后是R s?在Haskell中订购清单列表

+0

所以,[sortBy(http://www.haskell.org/ghc/文档/ 7.6-最新/ HTML /库/基4.6.0.1 /数据List.html#五:sortBy)? –

回答

3

使用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]] 
+2

'\ e1 e2 - >比较(长度e2)(长度e1)'=='flip $比较长度'。 – JJJ

+1

你可以通过导入'Data.ord.comparing'来让你的sortBy比较清洁。然后你可以写'sortBy(比较长度)l' – Squidly

+0

我实际上比'compare'想到更多'比较'。 :-) –

1

sortBy从和Data.List模块从comparing将Data.Ord帮助您。

foo = sortBy (comparing (negate . length)) 

bar = foo ["QQQ", "RRRR", "TTTTT"] 
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)