比较列表长度

发布于 2024-12-09 07:11:29 字数 352 浏览 1 评论 0原文

我有一个列表列表,比方说:

import Data.List

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

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

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

maximumBy (compare `on` length) xs

但出现以下错误:不在范围“on”

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

I have a list of lists, let's say:

import Data.List

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

I want to get the inner list with the most items, in this case [1,2,3].

I'm trying to use the maximumBy function from the Data.List library:

maximumBy (compare `on` length) xs

but I get the following error: not in scope 'on'

Can anyone tell me what is wrong, or if you have a better way to get the list?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

爱,才寂寞 2024-12-16 07:11:29

on数据中定义.Function,所以你需要导入它。

或者,您可以使用 数据.Ord

maximumBy (comparing length) xs

on is defined in Data.Function, so you need to import that.

Alternatively, you can use comparing from Data.Ord:

maximumBy (comparing length) xs
谁许谁一生繁华 2024-12-16 07:11:29

虽然使用 maximumBy比较长度比较 `on` 长度 对于短列表来说效果很好,但请注意,这不是一个非常好的方法。如果列表很长,则这是有效的解决方案,因为每次算法比较两个列表时,它都会重新计算它们的长度。

例如,如果我们有一个很长的第一个列表,后面跟着许多短列表,那么使用 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)

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

While using maximumBy with comparing length or compare `on` length will do the job just fine for short lists, note that this is not a very efficient solution if the lists are long, since each time the algorithm compares two lists, it will re-calculate their lengths.

For example, if we have a very long first list, followed by many short lists, using maximumBy will be very slow since the length of the first list will be re-calculated at each step.

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

We can get a more efficient solution by caching the lengths of the lists:

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

Of course, this might not make a big difference if your lists are small, but it's worth taking note of.

信愁 2024-12-16 07:11:29

或者你可以说得更明确一点:

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

也许这样更容易理解。

or you can make it a bit more explicit:

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

maybe it's easier to understand this way.

绅士风度i 2024-12-16 07:11:29

尝试

maximumBy (comparing length)

maximumBy (on compare length)

maximumBy (compare `on` length)

Try

maximumBy (comparing length)

or

maximumBy (on compare length)

or

maximumBy (compare `on` length)
饭团 2024-12-16 07:11:29

受到哈马尔解决方案的启发,但只需浏览一下列表即可:

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  

Inspired by hammar's solution, but with just one pass thru the list:

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  
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文