如何找到列表中最长的单词?

Jas*_*sta 19 haskell

我无法用一种功能性的思维方式来解决这个问题,这种方式也可以用于非常长的列表.如果您有以下列表:

["one", "two", "three", "four", "five"]
Run Code Online (Sandbox Code Playgroud)

我可以说出最长单词的长度非常简单:

maximum $ map length ["one", "two", "three", "four", "five"]
Run Code Online (Sandbox Code Playgroud)

如何修改前面的语句以返回字符串3

sth*_*sth 38

使用maximumBy,on并且compare你可以写这样的表达:

import Data.List (maximumBy)
import Data.Function (on)

maximumBy (compare `on` length)  ["one", "two", "three", "four", "five"]
Run Code Online (Sandbox Code Playgroud)

  • `比较\`on \`length`是`比较长度`,其中`comparison`来自`Data.Ord`. (6认同)

hvr*_*hvr 12

顺便说一下,如果一个没有现成的maximumBy,一个简单的方法就是装饰 - 排序 - 未装饰模式/习语(它也适用于其他语言,如Python或Scheme):

snd $ maximum $ map (\x -> (length x, x)) ["one", "two", "three", "four", "five"]
Run Code Online (Sandbox Code Playgroud)

但由于原始有效负载也是排序键的一部分,因此结果并不总是第一次出现最长的单词(在这种情况下,只有一个单词的长度最长)

  • 即使使用`maximumBy`,这也很有用.`maximumBy`函数将重新计算每次比较时最长当前令牌的长度(或正在使用的任何比较函数),而decorate-sort-undecorate仅计算一次长度.即使使用适度大小的输入,此版本也显着提高效率.当然,如果你使用任何长度的列表,你可能不应该使用列表. (3认同)
  • @hvr:decorate方法的问题是它需要x有一个Ord实例,即使你只是比较装饰.出于性能原因,您可以使用decorate方法和`maximumBy fst`来避免列表元素本身需要Ord. (2认同)

ide*_*ity 9

这个函数(甚至库)似乎并不为人所熟知,但是Haskell实际上有一个模块Data.Ord,它包含的函数comparing几乎就像Data.Function.on在最顶层的答案中使用一样,除了代码最终更加惯用.

g>import Data.Ord
g>import Data.List
g>let getLongestElement = maximumBy (comparing length)
getLongestElement :: [[a]] -> [a]
g>getLongestElement ["one", "two", "three", "four", "five"]
"three"
Run Code Online (Sandbox Code Playgroud)

该代码实际上读起来像英语."通过比较长度获得最大值."