Подтвердить что ты не робот

Как найти самое длинное слово в списке?

Я не могу понять свой ум в функциональном мышлении, чтобы решить эту проблему простым способом, который также мог бы работать для очень длинных списков. Если у вас есть список, например:

["one", "two", "three", "four", "five"]

Я могу сказать, что длина самого длинного слова довольно просто:

maximum $ map length ["one", "two", "three", "four", "five"]

Как мне изменить предыдущий оператор, чтобы вернуть строку три?

4b9b3361

Ответ 1

Используя maximumBy, on и compare вы можете написать выражение следующим образом:

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

maximumBy (compare `on` length)  ["one", "two", "three", "four", "five"]

Ответ 2

btw, если у вас не было готового к использованию maximumBy, простым способом было бы украшение-сортировка-undecorate pattern/idiom (работающая на других языках, таких как Python или Scheme):

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

Но так как исходная полезная нагрузка также является частью ключа сортировки, результат не всегда является первым вложением самого длинного слова (в этом случае было только одно слово с самой длинной длиной)

Ответ 3

Эта функция (или даже библиотека) не кажется хорошо известной, но у 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"

Код практически читается как английский. "Получите максимум, сравнивая длину".

Ответ 4

maximumBy (\x -> (x, length x)), fst и snd в простой композиции делают трюк.

Ответ 5

Чтобы вычислить length a, вам нужно пройти весь список a. В этом конкретном случае использования вас беспокоит только самое длинное слово, а не точно, как долго они длится, поэтому вы можете написать функцию, которая только заходит так далеко, насколько это необходимо в каждом списке, чтобы определить, какой из них самый длинный. Это может сэкономить вам некоторую обработку:

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

Ответ 6

foldl (\accmax xs -> if length accmax < length xs then xs else accmax) [] ["one", "two", "three", "four", "five"]