[英]haskell second largest element from list
I have this function that returns the second largest value from a given list:我有这个函数返回给定列表中的第二大值:
import Data.List
secondL :: Ord a => [a] -> a
secondL xs =
let x = head xs
in let find (a, b) x = (min b (max a x), max b x)
in fst (foldl find (x, x) xs)
This function should be working correctly, but for better purity I would like to exclude the function find
's definition which is inside, and rework this function so that there is no other function declaration inside.这个函数应该可以正常工作,但为了更好的纯度,我想排除里面的函数
find
的定义,并重新修改这个函数,以便里面没有其他函数声明。
I was thinking about including (min b (max ax), max bx)
into foldl
argument, but this doesn't seem to be working well.我正在考虑将
(min b (max ax), max bx)
到foldl
参数中,但这似乎效果不佳。
listToMaybe . take 1 . drop 1 . sortBy (flip compare)
:: Ord a => [a] -> Maybe a
will do this for you.会为你做这件事。 It is even linear, because Haskell is lazy, and Haskell's
sort
is mergesort.它甚至是线性的,因为 Haskell 是惰性的,而 Haskell 的
sort
是归并sort
。
If you meant second largest, not second among the largest, you can just stick a nub
in there to get it:如果你的意思是第二大,而不是第二大,你可以在那里贴一个
nub
来得到它:
listToMaybe . take 1 . drop 1 . nub . sortBy (flip compare)
:: Ord a => [a] -> Maybe a
It'll still be linear.它仍然是线性的。
Trying it out:尝试一下:
> listToMaybe . take 1 . drop 1 . nub . sortBy (flip compare) $ [1,3,2,3,1]
Just 2
> listToMaybe . take 1 . drop 1 . nub . sortBy (flip compare) $ [3,3,3]
Nothing
(use https://hoogle.haskell.org/ to search for functions) (使用https://hoogle.haskell.org/搜索函数)
If you want to code it with left fold specifically, then如果你想专门用左折叠对其进行编码,那么
foo :: Ord a => [a] -> Maybe a
foo xs
| [_,y] <- foldl' g [] xs = Just y
| otherwise = Nothing
where
g ys x = take 2 . nub . reverse . sort $ x:ys
Writing g
out by hand with all the comparisons and the checks needed (or itself as a fold) is left as an exercise.用所有需要的比较和检查(或本身作为折叠)手工写出
g
作为练习。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.