3

(我已经根据“removeall where”或“removeall two argument predicate”的关键字进行了尽可能多的搜索,但运气不佳,所以就这样吧)

问题是我有一个对象列表(属于 Wave 类)和一个关系函数: private bool AinB(Wave A, Wave B),如果 A '在'B 中,则返回 true。AinB(x,y) 也是 true保证 AinB(y,x) 为假。

删除列表中对象“位于”列表中另一个对象中的所有对象的最佳方法是什么?即,在删除之后,列表应该只包含与列表中的任何其他对象都不存在“存在”关系的对象?

理想情况下,这可以很容易地完成

listX.RemoveAll( (x,y) => AinB(x,y)) 但当然这在 C# 中是不合法的,也没有简单的方法来指定要删除哪个,x 或 y。

我想过用索引遍历列表

int i = listX.Count - 1;
while (i>=0)
{
    int r = listX.RemoveAll(X => AinB(X, listX[i]));
    i = i - r - 1;
}

这似乎可行,但我想知道是否有更好的方法使用直接 linq 代码来解决问题。谢谢。

4

3 回答 3

8

不幸的是,我想不出至少不是 O(n^2) 的任何方法。但好消息是,从 LINQ 的角度来看,这并不难:

listX.RemoveAll(item => listX.Any(isin => AinB(item, isin)));
于 2013-06-27T12:55:22.657 回答
0

使用正常的 for 循环,首先检查列表中的最高元素,直到最低元素。检查当前位置的元素是否存在列表中的任何重复项,如果发现删除当前元素(并可能减少您的迭代器)。

例子:

List<string> stuff = new List<string>(); //full of stuff
for(int i = stuff.Count - 1; i > 0; i--)
{
    //Edited here for more efficiency.
    for (int x = i - 1; x > 0; x--)
    {
        if (stuff[x] == stuff[i])
        {
            stuff.RemoveAt(i);
            break; //or possibly continue;
        }
    }
}

这是在这里手工编码的,所以它可能有一些语法错误,如果你发现有些地方不太正确,请随时给我编辑。

如果您是使用 LINQ 的向导,您还可以尝试将列表中的对象分组,然后为输出列表选择每个组中的第一个对象。

于 2013-06-27T13:05:22.297 回答
-2

您可以使用 LINQ 除了调用,

List a = new List();
a.Add("a");
a.Add("b");
a.Add("c");
List b = new List();
b.Add("b");
b.Add("c");
b.Add("d");
List c = a.Except(b);

列表 c 将仅包含项目“a”;

你甚至可以通过给出一个比较对象来让它更聪明,

List c = a.Except(b, new CompareObject());
于 2013-06-27T12:59:41.627 回答