List 比较列表长度

List 比较列表长度,list,haskell,List,Haskell,我有一个列表,比如: import Data.List xs = [[1,2], [1,2,3], [2,3]] 我想获得包含最多项的内部列表,在本例中为[1,2,3] 我正在尝试使用数据中的maximumBy函数。列表库: maximumBy (compare `on` length) xs 但我得到了以下错误:不在“on”范围内 有谁能告诉我出了什么问题,或者你有没有更好的方法来获取列表?试试看 maximumBy (comparing length) 或 或 中定义了上的,因此您需

我有一个列表,比如:

import Data.List

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

我正在尝试使用
数据中的
maximumBy
函数。列表
库:

maximumBy (compare `on` length) xs
但我得到了以下错误:
不在“on”范围内

有谁能告诉我出了什么问题,或者你有没有更好的方法来获取列表?

试试看

maximumBy (comparing length)


中定义了上的
,因此您需要导入它

或者,您可以从以下位置使用
比较


或者,您可以让它更明确一点:

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

也许这样更容易理解。

当使用
maximumBy
比较长度
compare`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)
>导入数据。列表
>导入数据.Ord
>设xs=replicate 50000“a”:replicate 50000“b”
>最大长度(比较长度)xs
(16.09秒,98338680字节)
通过缓存列表的长度,我们可以获得更高效的解决方案:

> let longest xss = snd $ maximumBy (comparing fst) [(length xs, xs) | xs <- xss]
> longest xs
<snip>
(0.35 secs, 91547296 bytes)
>让最长的xss=snd$maximumBy(比较fst)[(长度xs,xs)| xs最长的xs
(0.35秒,91547296字节)

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

受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  

谢谢,成功了…我不知道我需要另一个库。Haskell Noob在这里。是的,我需要…等5分钟!@Special--k非常适合计算需要从哪个模块导入函数。没有其他非重新计算版本的
maximumBy
?顺便问一句,如何让
ghci
打印运行时?@Tarrasch:没有我认为,在任何标准库中都可以使用
:set+s
来启用每次计算的计时。@Tarrasch:显然,但它似乎已被放弃。作为练习,尝试不要在
上使用
,而是手动将参数写入
maximumBy
maximumBy(\x y->…)xs
> 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)
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