如何在C#

时间:2019-08-21 13:06:41

标签: c#

这与Given 2 C# Lists how to merge them and get only the non duplicated elements from both lists不重复,因为他正在查看相同类型的列表。

我有这种情况:

class A
{
    string id;
    .... some other stuff
}

class B
{
    string id;
    .... some other stuff
}

我想从A和B中删除在两个列表之间共享id字段的元素。

我可以分3个步骤进行操作:找到通用ID,然后从两个列表中删除记录,但是我想知道是否还有更优雅的方法。


编辑:预期输出

  

var A = [1,3,5,7,9]   var B = [1,2,3,4,5]

输出:

  

A = [7,9]   B = [2,4]

,但这仅显示id字段;如上所述,列表的类型不同,它们只是共享ID。

4 个答案:

答案 0 :(得分:1)

您将需要三个步骤,但是您可以使用Linq简化代码。

给出两个具有相同(相等)类型的属性的类,命名为“ ID”:

gcloud auth application-default login

然后,您可以找到重复项并将其从两个列表中删除,如下所示:

class Test1
{
    public string ID { get; set; }
}

class Test2
{
    public string ID { get; set; }
}

但这仍然是三个步骤。

有关可运行的示例,请参见.Net Fiddle example

答案 1 :(得分:0)

您可以使用LINQ Lambda表达式来实现优雅:

var intersectValues = list2.Select(r => r.Id).Intersect(list1.Select(r => r.Id)).ToList();
list1.RemoveAll(r => intersectValues.Contains(r.Id));
list2.RemoveAll(r => intersectValues.Contains(r.Id));

答案 2 :(得分:0)

基于@Matthew Watson的答案,您可以使用

将其全部移动到单个LINQ表达式中。

(from item1 in list1
 join item2 in list2 on item1.ID equals item2.ID
 select item1.ID)
   .ToList()
     .ForEach(d => 
     {
         list1.RemoveAll(i1 => d == i1.ID);
         list2.RemoveAll(i2 => d == i2.ID);
     }
);

我不知道您在绩效方面的地位。实际上,编译器可能会将其分为您已经提到的三个步骤。

您还失去了一些可读性,因为from ... select结果没有像 duplicates 这样的“口语”名称,直接告诉您在{{1} }。

位于https://gist.github.com/msdeibel/d2f8a97b754cca85fe4bcac130851597

的完整代码示例

答案 3 :(得分:0)

O(n)

        var aHash = list<A>.ToHashSet(x=>x.ID);
        var bHash = list<B>.ToHashSet(x=>x.ID);
        var result1 = new List<A>(A.Count);
        var result2 = new List<B>(B.Count);
        int value;
        foreach (A item in list<A>)
        {
            if (!bHash.TryGetValue(item.ID, out value))
                result1.Add(A);
        }
        foreach (B item in list<B>)
        {
            if (!aHash.TryGetValue(item.ID, out value))
                result2.Add(B);
        }