I can't get my mind in a functional mindset to solve this problem in a simple way that could also work for very long lists. If you have a list like:
["one", "two", "three", "four", "five"]
I can tell what the length of the longest word is pretty simply with:
maximum $ map length ["one", "two", "three", "four", "five"]
How would I modify the previous statement to return the string three?
Find the length of the longest word using the len() (The number of items in an object is returned by the len() method. It returns the number of characters in a string when the object is a string) and max() (returns the highest-valued item, or the highest-valued item in an iterable) functions from the above words list.
Use Python's built-in max() function with a key argument to find the longest string in a list. Call max(lst, key=len) to return the longest string in lst using the built-in len() function to associate the weight of each string—the longest string will be the maximum.
Using maximumBy
, on
and compare
you can write the expression like this:
import Data.List (maximumBy)
import Data.Function (on)
maximumBy (compare `on` length) ["one", "two", "three", "four", "five"]
btw, if one had no ready-to-use maximumBy
, a simple way would be the decorate-sort-undecorate pattern/idiom (which works in other languages like Python or Scheme as well):
snd $ maximum $ map (\x -> (length x, x)) ["one", "two", "three", "four", "five"]
But since the original payload is also part of the sort-key, the result is not always the first occurrence of the longest word (in this case there was only one word with the longest length)
This function(or even library) doesn't seem to be well known, but Haskell actually has a module called Data.Ord
which contains the function comparing
which is almost like using Data.Function.on
in the top answer, except the code ends up more idiomatic.
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"
The code practically reads like English. "Get maximum by comparing length."
maximumBy
(\x -> (x, length x))
, fst
, and snd
in a straightforward composition do the trick.
To compute length a
, you need to traverse the entire list a
. In this particular use case, you are only concerned about the longest word, and not exactly how long they are, so you may write a function that only go as far as it is needed in each list to determine which one is the longest. This may save you some processing:
module Main where
main = putStrLn $ longestWordInList ["one", "two", "three", "four"]
longestWordInList = go ""
where go result [] = result
go result (x:xs) = let result' = longestWord result x in
result' `seq` go result' xs
longestWord a b = go a b a b
where go a _ _ [] = a
go _ b [] _ = b
go a b (_:as) (_:bs) = go a b as bs
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With