C#通用列表联合问题 [英] C# Generic List Union Question
问题描述
我试图用Union合并2个列表,所以我摆脱了重复。以下是示例代码:
public class SomeDetail
{
public string SomeValue1 {get;组; }
public string SomeValue2 {get;组; }
public string SomeDate {get;组; }
}
public class SomeDetailComparer:IEqualityComparer< SomeDetail>
{
bool IEqualityComparer< SomeDetail> .Equals(SomeDetail x,SomeDetail y)
{
//检查比较对象是否引用相同的数据。
if(Object.ReferenceEquals(x,y))
返回true;
//检查是否有比较的对象为空。
if(Object.ReferenceEquals(x,null)|| Object.ReferenceEquals(y,null))
return false;
return x.SomeValue1 == y.SomeValue1&& x.SomeValue2 == y.SomeValue2;
}
int IEqualityComparer< SomeDetail> .GetHashCode(SomeDetail obj)
{
return obj.SomeValue1.GetHashCode();
}
}
List< SomeDetail> tempList1 =新列表< SomeDetail>();
列表< SomeDetail> tempList2 =新列表< SomeDetail>();
列出< SomeDetail> detailList = tempList1.Union(tempList2,SomeDetailComparer).ToList();
现在问题是我可以使用Union并仍然获取具有最新日期的记录(使用SomeDate属性)。记录本身可以在tempList1或tempList2中。
在此先感谢
非常适合此目的的操作是完整的外连接。 Enumerable
类有一个内部连接的实现,您可以使用它来查找重复项并选择您喜欢的任何项。
< (item1,item2)=>(item1.SomeDate> item2.SomeDate)?item1(item1,item2,item2.SomeDate)?item1 :item2)
.ToList();
keySelector
只是一个函数一个lambda表达式),它从 SomeDetail
类型的对象中提取一个键。现在,要实现完整的外连接,请尝试如下所示:
var keyComparer =(SomeDetail item)=> new {Value1 = item.SomeValue1,
Value2 = item.SomeDetail2};
var detailList = Enumerable.Union(tempList1.Except(tempList2,equalityComparer),
tempList2.Except(tempList1,equalityComparer))。Union(
Enumerable.Join(tempList1,tempList2,keyComparer, keyComparer
(item1,item2)=>(item1.SomeDate> item2.SomeDate)?item1:item2))
.ToList();
equalityComparer
应该是一个对象, code> IEqualityComparer< SomeDetail> ,并有效地使用 keyComparer
函数来测试相等性。
让我知道这是否适合你。
I'm trying to merge 2 lists using "Union" so I get rid of duplicates. Following is the sample code:
public class SomeDetail
{
public string SomeValue1 { get; set; }
public string SomeValue2 { get; set; }
public string SomeDate { get; set; }
}
public class SomeDetailComparer : IEqualityComparer<SomeDetail>
{
bool IEqualityComparer<SomeDetail>.Equals(SomeDetail x, SomeDetail y)
{
// Check whether the compared objects reference the same data.
if (Object.ReferenceEquals(x, y))
return true;
// Check whether any of the compared objects is null.
if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
return false;
return x.SomeValue1 == y.SomeValue1 && x.SomeValue2 == y.SomeValue2;
}
int IEqualityComparer<SomeDetail>.GetHashCode(SomeDetail obj)
{
return obj.SomeValue1.GetHashCode();
}
}
List<SomeDetail> tempList1 = new List<SomeDetail>();
List<SomeDetail> tempList2 = new List<SomeDetail>();
List<SomeDetail> detailList = tempList1.Union(tempList2, SomeDetailComparer).ToList();
Now the question is can I use Union and still get the record which has the latest date (using SomeDate property). The record itself can either be in tempList1 or tempList2.
Thanks in advance
The operation that is really suited to this purpose is an full outer join. The Enumerable
class has an implementation of inner join, which you can use to find the duplicates and select whichever you prefer.
var duplicates = Enumerable.Join(tempList1, tempList2, keySelector, keySelector,
(item1, item2) => (item1.SomeDate > item2.SomeDate) ? item1 : item2)
.ToList();
keySelector
is simply a function (could be a lambda expression) that extracts a key from an object of type SomeDetail
. Now, to implement the full outer join, try something like this:
var keyComparer = (SomeDetail item) => new { Value1 = item.SomeValue1,
Value2 = item.SomeDetail2 };
var detailList = Enumerable.Union(tempList1.Except(tempList2, equalityComparer),
tempList2.Except(tempList1, equalityComparer)).Union(
Enumerable.Join(tempList1, tempList2, keyComparer, keyComparer
(item1, item2) => (item1.SomeDate > item2.SomeDate) ? item1 : item2))
.ToList();
equalityComparer
should be an object that implements IEqualityComparer<SomeDetail>
and effectively uses the keyComparer
function for testing equality.
Let me know if that does the job for you.
这篇关于C#通用列表联合问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!