如何从Haskell中的两个列表中提取相同的元素?

如何从Haskell中的两个列表中提取相同的元素?,haskell,Haskell,我的问题是: 如何将相同的元素从两个等长列表提取到另一个列表? 例如:给定两个列表[2,4,6,3,2,1,3,5]和[7,3,3,2,8,8,9,1],答案应该是[1,2,3,3]。请注意,订单并不重要。我实际上是在使用返回列表的长度 我试过这个: sameElem as bs = length (nub (intersect as bs)) 但问题是nub会删除所有重复项。将我的函数用于前一个示例的结果是3长度[1,3,2],而不是4长度[1,3,3,2]。有解决办法吗?谢谢。由于位置似乎

我的问题是: 如何将相同的元素从两个等长列表提取到另一个列表? 例如:给定两个列表
[2,4,6,3,2,1,3,5]
[7,3,3,2,8,8,9,1]
,答案应该是
[1,2,3,3]
。请注意,订单并不重要。我实际上是在使用返回列表的长度

我试过这个:

sameElem as bs = length (nub (intersect as bs))

但问题是
nub
会删除所有重复项。将我的函数用于前一个示例的结果是
3
长度
[1,3,2]
,而不是
4
长度
[1,3,3,2]
。有解决办法吗?谢谢。

由于位置似乎不相关,您只需事先对列表进行排序,然后遍历两个列表:

import Data.List (sort)

intersectSorted :: Ord a => [a] -> [a] -> [a]
intersectSorted (x:xs) (y:ys) 
 | x == y    = x : intersectSorted xs ys
 | x < y     = intersectSorted xs (y:ys)
 | x > y     = intersectSorted (x:xs) ys
intersectSorted _ _ = []

intersect :: Ord a => [a] -> [a] -> [a]
intersect xs ys = intersectSorted (sort xs) (sort ys)

您可以为此编写一个函数。可能有一个更优雅的版本涉及lambda's或褶皱,但这确实适用于您的示例:

import Data.List

same (x:xs) ys = if x `elem` ys
                 then x:same xs (delete x ys)
                 else same xs ys
same [] _ = []
same _ [] = []
then子句中的
delete x ys
非常重要,如果第一个列表中的delete命令项至少出现一次,则每次遇到它们时都会被计数。
请注意,输出没有排序,因为您只对结果列表的长度感兴趣

import Data.List (delete)

mutuals :: Eq a => [a] -> [a] -> [a]
mutuals []       _                = []
mutuals (x : xs) ys | x `elem` ys = x : mutuals xs (delete x ys)
                    | otherwise   = mutuals xs ys
给予


如示例所示,该职位与此相关吗?如果是这样,您可以将列表压缩到[(1,1),(3,3),(3,3),(2,2),(4,5)…]并删除fst不在snd中的条目。此处的位置不相关。我改变了这个例子。谢谢。好的,还有另一个类似的解决方案。请注意,
(\l->\k->[x | xNikolajK,或者您可以在结果的Data.List中使用nub来删除重复项。@fgv:No,如果他通过
[7,9,7]
[3,7,7,7]
,他希望输出是
[7,7]
,参见上面的示例。我的方法将首先找到六对,根据索引进行删除将删除其中四对,从而得到正确的结果。如果我们只应用
nub
,那么我们总是只找到一对。很抱歉,我给出的示例不合适。实际上,位置应该无关紧要。@user3928256:Note t您当前的示例在结果中缺少一个
2
。这也可以通过
zip
来完成:
intersectSorted::Eq a,Ord a=>[a]->[a]->[a]->[a]->[a]->[a]->[a]->[a]->[a]->[a]->[a]->[a]->[a]->[a]->[a]->[a]->[a]->[a]->[a];intersectsortedL k=filter(\(x,y)==y)$zip(sort l)(sort l)(sort l)(sort k)
@C
。排序列表的
zip
没有任何值相等的对,但是交集应该是
[1,4]
@dfeuer。我想我太喜欢'14'中的无意义样式了。我还替换了
uncurry(翻转复制)
,因为lambda更容易阅读。谢谢!这正是我在Java中要做的。我以前不知道Haskell中的“delete”。
import Data.List (delete)

mutuals :: Eq a => [a] -> [a] -> [a]
mutuals []       _                = []
mutuals (x : xs) ys | x `elem` ys = x : mutuals xs (delete x ys)
                    | otherwise   = mutuals xs ys
mutuals [2,4,6,3,2,1,3,5] [7,3,3,2,8,8,9,1]  ==  [2,3,1,3]