合并列表中的等效项

时间:2011-11-17 21:50:45

标签: haskell

假设我有以下类型

type Key = String
type Score = Int
data Thing = Thing Key Score

如果我有这样的数组:

[Thing "a" 7, Thing "b" 5, Thing "a" 10]

是否有一种标准方法可以减少这种情况,以便我没有任何重复的密钥?如果两个键匹配,我想取得更好的分数

[Thing "b" 5, Thing "a" 10]

4 个答案:

答案 0 :(得分:6)

一个非常简单的解决方案是使用Data.Map.fromListWith,它将键值对列表转换为映射,给定一个函数将多个值与相同的键组合。

Prelude Data.Map> fromListWith max [("a", 7), ("b", 5), ("a", 10)]
fromList [("a",10),("b",5)]

请注意,这需要元组,因此必要时进行转换。此外,它不保留输入元素的顺序。运行时间为O(n log n)。

答案 1 :(得分:5)

首先,我们必须首先确定解决问题的方法以及实施难点。那么如果我们首先按Score排序,然后只保留排序列表中第一次出现的Key?这应该工作,让我们来看看haskell实现:

import Data.List
import Data.Function

type Key = String
type Score = Int
data Thing = Thing { key :: Key, score :: Score }
  deriving (Show)

myNub  = nubBy  ((==) `on` key)
mySort = sortBy (compare `on` (negate . score))

selectFinest = myNub . mySort

现在我们尝试在ghci

中运行此功能
Prelude> :load Test.hs 
[1 of 1] Compiling Main             ( Test.hs, interpreted )
Ok, modules loaded: Main.
*Main> selectFinest [Thing "a" 7, Thing "b" 5, Thing "a" 10]
[Thing {key = "a", score = 10},Thing {key = "b", score = 5}]

如果您不确定我在解决方案中使用的功能,请结帐hoogle。确实需要一些时间来学习如何使用on和那些函数。

答案 2 :(得分:1)

我发布了一个O(n log n)解决方案,因为每个人看起来都很好O(n ^ 2)

consolidate :: (Ord a, Ord b) => [Thing a b] -> [Thing a b]
consolidate xs = 
    max_from_each_group (sortBy (compare `on` getKey) xs)
    where
       max_from_each_group [] = []
       max_from_each_group (x:xs) = 
           let (same_key, rest) = span (\t -> x == getKey t) xs in
           let group_max = maximumBy (compare `on` getValue) (x:same_key) in
           group_max : max_from_each_group rest

答案 3 :(得分:0)

这是我的微弱尝试。肯定有一个更好的方式,但我不是 很多Haskell程序员。

import Data.List

type Key = String
type Score = Int
data Thing = Thing Key Score
           deriving (Show, Ord)

instance Eq Thing where
    (Thing k1 _) == (Thing k2 _) = k1 == k2
    (Thing k1 _) /= (Thing k2 _) = k1 /= k2

thingSort :: [Thing] -> [Thing]
thingSort = Data.List.sortBy (flip compare)

ex = [Thing "a" 7, Thing "b" 5, Thing "a" 10]

filtered = nub (thingSort ex)