这与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。
答案 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);
}