繁体   English   中英

如何在元组列表中找到所有最小元素?

[英]How to find all minimum elements in a list of tuples?

如何找到列表中的所有最小元素? 现在我有一个元组列表,即

[(10,'a'),(5,'b'),(1,'c'),(8,'d'),(1,'e')]

所以我想要 output 这是列表的所有最小元素,在一个新列表中。 例如

 [(1,'c'),(1,'e')]

我试过了

minimumBy (comparing fst) xs

但这只返回第一个最小元素。

在您获得第一个值的最小值后,我们可以过滤这些项目的列表。 因为您在这里要检索最少项目的列表,所以我们也可以通过返回一个空列表来覆盖空列表:

minimumsFst :: Ord a => [(a, b)] -> [(a, b)]
minimumsFst [] = []
minimumsFst xs = filter ((==) minfst . fst) xs
    where minfst = minimum (map fst xs)

例如:

Prelude> minimumsFst [(10,'a'),(5,'b'),(1,'c'),(8,'d'),(1,'e')]
[(1,'c'),(1,'e')]

单线。 关键是排序。

Prelude Data.List> let a = [(1,'c'),(2,'b'),(1,'w')]
Prelude Data.List> (\xs@((m,_):_) -> takeWhile ((== m) . fst ) xs) . sortOn fst $ a
[(1,'c'),(1,'w')]

您也可以使用foldr轻松完成:

minimumsFst :: Ord a => [(a, b)] -> [(a, b)]
minimumsFst xs = go (minfst xs) xs
  where
  go mn ls = foldr (\(x, y) rs -> if (x ==  mn) then (x,y) : rs else rs) [] xs
  minfst ls = minimum (map fst ls)

用你的例子:

   minimumsFst [(10,'a'),(5,'b'),(1,'c'),(8,'d'),(1,'e')]
=> [(1,'c'),(1,'e')]

你试过

minimumBy (comparing fst) xs

也可以写成

= head . sortBy (comparing fst) $ xs
= head . sortOn fst $ xs
= head . head . group . sortOn fst $ xs
= head . head . groupBy ((==) `on` fst) . sortOn fst $ xs

这仅返回第一个元素而不是它们的列表,因此只需放下多余的head即可获得所需的内容:

=        head . groupBy ((==) `on` fst) . sortOn fst $ xs

当然有head是不好的,因为它会在[]输入上出错。 相反,我们可以使用安全选项,

= concat . take 1 . groupBy ((==) `on` fst) . sortOn fst $ xs

顺便说一句,任何调用minimum的解决方案对于空输入列表也是不安全的:

 > head [] *** Exception: Prelude.head: empty list > minimum [] *** Exception: Prelude.minimum: empty list

但是takeWhile是安全的:

 > takeWhile undefined [] []

编辑:由于懒惰,即使在最坏的情况下,最终版本的整体时间复杂度仍应为O(n)

这是一个一次性工作的解决方案(这里的大多数其他答案都做了两次:一次找到最小值,一次过滤),并且不依赖于如何实现排序功能以提高效率。

{-# LANGUAGE ScopedTypeVariables #-}

import Data.Foldable (foldl')

minimumsBy :: forall a. (a -> a -> Ordering) -> [a] -> [a]
minimumsBy _ [] = []
minimumsBy f (x:xs) = postprocess $ foldl' go (x, id) xs
  where
    go :: (a, [a] -> [a]) -> a -> (a, [a] -> [a])
    go acc@(x, xs) y = case f x y of
      LT -> acc
      EQ -> (x, xs . (y:))
      GT -> (y, id)
    postprocess :: (a, [a] -> [a]) -> [a]
    postprocess (x, xs) = x:xs []

请注意,我在这里使用的[a] -> [a]类型称为差异列表,也称为休斯列表

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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