比较两个List排序

时间:2015-05-08 15:50:54

标签: list haskell merge compare

我有这个编解码器,但它没有显示重复的元素,为什么?

doc.Open();

输入:两个列表排序。

List1 = cosinesim :: Ord a => [(a,Float)] -> [(a,Float)] -> [(a,Float,Float)] cosinesim a b = go a b where go [] b = map (\l -> (fst l, 0, snd l)) b go a [] = map (\l -> (fst l, snd l, 0)) a go a@((x,n):t) b@((y,m):r) = case compare x y of LT -> (x,n,0) : go t b EQ -> (x,n,m) : go t r GT -> (y,0,m) : go a r

List2 = [(["variety"], 4.50),(["vegetable"], 3.50),(["velvet"], 2.50)]

输出:

[(["variety"], 4.50),(["ve"], 3.50),(["velvet"], 2.50)]

我的问题是因为只显示在两个列表中重复的元素,因为我想要的是所有元素都出现。

1 个答案:

答案 0 :(得分:1)

由于您希望合并两个列表的元素,保持密钥的唯一性,我建议您使用Map中的Data.Map。然后,您可以使用unionunionWithunionWithKey合并两张地图。不过,第二个在这里会更有用。由于您还希望仅使用0指示值来自第一个或第二个列表,因此最好有一个明确表示该数据的数据类型:

import qualified Data.Map as M

data Those a b
    = This a        -- Only left
    | Those a b     -- Both
    | That b        -- Only right
    deriving (Eq, Show)

this :: a -> Those a b -> a
this def (This a)    = a
this def (Those a b) = a
this def _           = def

that :: b -> Those a b -> b
that def (That b)    = b
that def (Those a b) = b
that def _           = def

-- Give this a better name than Items
type Items k = M.Map k (Those Float Float)

这只是设置了我们稍后会使用的几种类型和工具。 Those类型代表左,右或两者,thisthat组合器可帮助我们轻松地从中提取值,就像{{1}中的maybe组合子一样}}

Prelude

listToLeftItems :: Ord a => [(a, Float)] -> Items a listToLeftItems = M.fromList . map (fmap This) listToRightItems :: Ord a => [(a, Float)] -> Items a listToRightItems = M.fromList . map (fmap That) cosinesim :: Ord a => [(a, Float)] -> [(a, Float)] -> [(a, Float, Float)] cosinesim left right = map (\(key, those) -> (key, this 0 those, that 0 those)) $ M.toList $ M.unionWith go (listToLeftItems left) (listToRightItems right) where go leftVal rightVal = case (leftVal, rightVal) of (This a, That b) -> Those a b (x, y) -> y -- We know we won't have any other combinations, -- this just keeps the compiler from throwing a warning 只会将listToLeftItems应用于列表中的每个This,然后将其转换为Float,同样适用于Map。现在,您的函数只是将输入列表转换为listToRightItems s,使用Map(我认为这很容易理解)将它们联合起来,转换回列表,然后展平go(a, Those Float Float)。它为您提供所需的结果,但不是以相同的顺序。如果重要的话,您可以使用它作为按顺序获取它的基础。