删除对重复Haskell

时间:2016-03-30 19:21:43

标签: haskell

给出一对配对列表,例如

[(1, 2), (1, 3), (1, 4), (2, 1), (3, 1), (4, 1)]

所以,我试图删除重复对,我认为如果(x,y)==(y,x),一对是重复的,例如:(1,2)with(3,1)< / p>

我正在使用理解列表生成列表,它来自一个列表

MyList = [(intA, intB) | x <- integerList, y <- integerList, x /= y]
integerList = [1, 2, 3];

请注意,我写的第一件事只是我想要发生的事情的一个例子,它不是上面的理解列表的输出。

我最近开始使用Haskell,我该如何处理这个问题?什么是最好的选择?我尝试使用地图,但没有成功,我应该将地图与在其中使用反向的foldl / foldr组合吗?我该怎么做?

3 个答案:

答案 0 :(得分:8)

这是使用Hoogle的最佳时机!让我们考虑一下你在寻找什么。要删除重复项,我们需要一些包含列表[a]并从中删除内容的内容,并根据某些谓词[a]返回a -> a -> Bool。这意味着我们正在寻找具有以下形式的函数:

ourFunction :: (a -> a -> Bool) -> [a] -> [a]

我们实际上可以使用函数签名(a -> a -> Bool) -> [a] -> [a]搜索Hoogle,第一个结果是nubBy,这正是我们想要的!

话虽如此,您不需要使用它来解决您的问题。你已经走上正轨了。想一想你在问什么 - 你想要(x, y) == (y, x)没有重复的元组。因此,只需选择是否需要y < x或其他方式,并在列表理解中使用它:

> let fn xs = [(a, b) | a <- xs, b <- xs, a < b]
> fn [1, 2, 3]
[(1,2),(1,3),(2,3)]

如果你需要两个列表(一个有重复,一个没有),我建议使用两个单独的列表推导。它的性能较差,因为你编写的列表理解是O(n ^ 2),但在我看来,它更清晰,更容易学习。

答案 1 :(得分:4)

#define MyAppName "TESTPROG"
[Setup]

AppName={#MyAppName}
DefaultDirName=C:\test\{#MyAppName}
DefaultGroupName={#MyAppName}

[Code]
var
  Page: TInputDirWizardPage;
  DataDir: String;

procedure InitializeWizard;
begin
  Page := CreateInputDirPage(wpWelcome,
    'Select Personal Data Location', 'Where should personal data files be stored?',
    'Personal data files will be stored in the following folder.'#13#10#13#10 +
    'To continue, click Next. ' +
      'If you would like to select a different folder, click Browse.',
    False, 'New Folder');

  Page.Add('Local APP');
  Page.Add('Local Storage');

  Page.Values[0] := ('C:\My Program');
  Page.Values[1] := ('D:\My Program');

  DataDir := Page.Values[0]; 
end;

或编写自己的版本

答案 2 :(得分:0)

它不是直接回答问题,但是有一种更简单的解决方案适用于这种情况(数字元组),只是在生成列表时添加一个过滤器,以确保后一个元素始终大于前一个元素

MyList = [(x, y)| x <- integerList, y <- integerList, x /= y, x < y]