简体   繁体   English

haskell 列表中的第二大元素

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM