我有一个元组列表,input: [("r","w"),("n","j"),("a","j"),("d","i"),("s","g"),("r","a")]
output: [("r","w"),("n","j"),("d","i"),("s","g")]
对。我需要删除复制键或值的元素,列表的顺序可以更改,但键的第一次出现或值必须保留在元组列表中:
示例:
removeDuplicates _ [] = []
removeDuplicates seen (x:xs)
| elem (head $ fst x) (fst seen) = [] ++ removeDuplicates seen xs
| elem (head $ snd x) (snd seen) = [] ++ removeDuplicates seen xs
| otherwise = x:removeDuplicates ((fst seen)++(fst x),(snd seen)++(snd x)) xs
我做了什么:
removeDuplicates ("","") something
但这需要被称为self.addEventListener('notificationclick', function(event) {
console.log('Notification click: tag ', event.notification.tag);
event.notification.close();
var url = 'https://youtu.be/gYMkEMCHtJ4';
event.waitUntil(
clients.matchAll({
type: 'window'
})
.then(function(windowClients) {
for (var i = 0; i < windowClients.length; i++) {
var client = windowClients[i];
if (client.url === url && 'focus' in client) {
return client.focus();
}
}
if (clients.openWindow) {
return clients.openWindow(url);
}
})
);
});
,这很丑陋。
答案 0 :(得分:4)
您可以使用Data.List
包中的nubBy
函数和相应的比较器:
removeDuplicates xs = nubBy cmpKeyAndVal xs
where
cmpKeyAndVal (x, y) (x', y') = x == x' || y == y'
用作:
> removeDuplicates [("r","w"),("n","j"),("a","j"),("d","i"),("s","g"),("r","a")]
[("r","w"),("n","j"),("d","i"),("s","g")]
另请注意,当密钥或值为("", "")
时,使用""
调用您的实现会产生错误的结果。选择正确的第一个参数的唯一方法是放置一些没有出现在输入中的东西,这有点烦人。
请注意,上述实现需要O(n ^ 2)时间,这对Eq
个实例来说是最佳的。如果您允许Ord
约束,则可以使用实现稳定排序算法的sortBy
函数,然后使用groupBy
删除连续的重复项:< / p>
import Data.List(sortBy, groupBy)
import Data.Ord(comparing)
import Data.Function(on)
removeDuplicates xs = sortAndGroupBy snd (sortAndGroupBy fst xs)
where
sortAndGroupBy f = map head . groupBy ((==) `on` f). sortBy (comparing f)
这需要O(nlog n)时间,但显然需要Ord
约束。
答案 1 :(得分:0)
首先,养成在编写函数时添加类型签名的习惯。它让你保持理智和诚实,它可以捕捉你想要做的事情,并且在你实现你的功能之前最好写出来。
removeDuplicates :: (Eq a, Eq a1) => ([a], [a1]) -> [([a], [a1])] -> [([a], [a1])]
如果你想在没有附加参数的情况下调用它,我建议这样:
remove :: (Eq a, Eq a1) => [([a], [a1])] -> [([a], [a1])]
remove = removeDuplicates ("","")
另一个更通用的版本不能仅使用列表作为元组的元素,将是这样的:
removeX :: (Eq t, Eq s) => [(t, s)] -> [(t, s)]
removeX [] = []
removeX (xx@(x,y):xs) = let xs' = filter (\(a,b) -> not (a == x || b ==y) ) xs
in xx:removeX xs'
如果您想坚持标准功能 - @Bakuriu为您提供正确的答案
答案 2 :(得分:0)
将累加器放在辅助函数中。
removeDuplicates lst = rd lst []
where rd _ [] = []
rd seen (x:xs) = ...