比较列表长度

时间:2011-10-11 17:41:44

标签: list haskell

我有一份清单,让我们说:

import Data.List

xs = [[1,2], [1,2,3], [2,3]]

我希望获得包含最多项目的内部列表,在本例中为[1,2,3]

我正在尝试使用maximumBy库中的Data.List函数:

maximumBy (compare `on` length) xs

但是我收到以下错误:not in scope 'on'

任何人都可以告诉我出了什么问题,或者你有更好的方法来获取清单吗?

5 个答案:

答案 0 :(得分:9)

{p> onData.Function中定义,因此您需要导入该内容。

或者,您可以使用Data.Ord中的comparing

maximumBy (comparing length) xs

答案 1 :(得分:8)

maximumBycomparing lengthcompare `on` length一起使用可以很好地处理短列表,但请注意,如果列表很长,这不是一个非常有效的解决方案,因为每次算法比较两个列表,它将重新计算它们的长度。

例如,如果我们有一个非常长的第一个列表,后面是很多短列表,使用maximumBy将非常慢,因为第一个列表的长度将在每一步重新计算。

> import Data.List
> import Data.Ord
> let xs = replicate 50000 'a' : replicate 50000 "b"
> maximumBy (comparing length) xs
<snip>
(16.09 secs, 98338680 bytes)

我们可以通过缓存列表的长度来获得更有效的解决方案:

> let longest xss = snd $ maximumBy (comparing fst) [(length xs, xs) | xs <- xss]
> longest xs
<snip>
(0.35 secs, 91547296 bytes)

当然,如果您的名单很小,这可能不会产生很大的影响,但值得注意。

答案 2 :(得分:4)

尝试

maximumBy (comparing length)

maximumBy (on compare length)

maximumBy (compare `on` length)

答案 3 :(得分:4)

或者你可以更明确一点:

xs = [[1,2],[1,2,3],[2,3]]
ordLen a b = compare (length a) (length b)
maximumBy ordLen xs

也许这种方式更容易理解。

答案 4 :(得分:1)

受到hammar解决方案的启发,但只有一次通过列表:

import Data.List

longest = snd . foldl' cmp (0,[]) where
   cmp maxPair@(maxLen, _) list = 
      let len = length list 
      in if len > maxLen then (len, list) else maxPair