C#List removeall在谓词中带两个参数?

时间:2013-06-27 12:50:57

标签: c# list removeall

(我已尽可能多地根据“removeall where”或“removeall two argument predicate”的关键字进行搜索而没有太多运气,所以这里就去了)

问题是我有一个对象列表(Class Wave)和一个关系函数: 私人布尔AinB(Wave A,Wave B),如果A'在'B中,则返回true。另外AinB(x,y)为真,保证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代码来解决问题。 谢谢。

3 个答案:

答案 0 :(得分:7)

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

listX.RemoveAll(item => listX.Any(isin => AinB(item, isin)));

答案 1 :(得分: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的向导,您还可以尝试对列表中的对象进行分组,然后只选择输出列表的每个组中的第一个对象。

答案 2 :(得分:-2)

你可以使用LINQ Except调用,

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());