我有一份清单,让我们说:
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'
任何人都可以告诉我出了什么问题,或者你有更好的方法来获取清单吗?
答案 0 :(得分:9)
答案 1 :(得分:8)
将maximumBy
与comparing length
或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)
我们可以通过缓存列表的长度来获得更有效的解决方案:
> 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