[英]Join two list comparing their elements properties
public class Person()
{
int ID;
string Name;
DateTime ChangeDate
}
var list1 = new List<Person>
{
new Person { ID= 1, Name = "Peter", ChangeDate= "2011-10-21" },
new Person { ID= 2, Name = "John", ChangeDate= "2011-10-22" },
new Person { ID= 3, Name = "Mike", ChangeDate= "2011-10-23" },
new Person { ID= 4, Name = "Dave", ChangeDate= "2011-10-24" }
};
var list2 = new List<Person>
{
new Person { ID= 1, Name = "Pete", ChangeDate= "2011-10-21" },
new Person { ID= 2, Name = "Johny", ChangeDate= "2011-10-20" },
new Person { ID= 3, Name = "Mikey", ChangeDate= "2011-10-24" },
new Person { ID= 5, Name = "Larry", ChangeDate= "2011-10-27" }
};
作為輸出,我希望有list1 + list2 =
Person { ID= 1, Name = "Peter", ChangeDate= "2011-10-21" },
Person { ID= 2, Name = "John", ChangeDate= "2011-10-22" },
Person { ID= 3, Name = "Mikey", ChangeDate= "2011-10-24" },
Person { ID= 4, Name = "Dave", ChangeDate= "2011-10-24" }
Person { ID= 5, Name = "Larry", ChangeDate= "2011-10-27" }
算法是這樣的。 加入兩個列表。 如果列表中的元素具有相同的ID,請按ChangeDate比較它們,並使用較大日期的ond。 如果ChangeDate是相等的,則選擇其中任何一個,但不能同時使用兩者。 也許同時合並兩個列表並比用lambda過濾列表更容易。 我試過了,但是總是出一些丑陋的代碼:/
有人知道嗎
LINQ
var q = from person in list1.Concat(list2)
group person by person.ID into g
select g.OrderByDescending(p => p.ChangeDate).First();
合並兩個按降序排序的列表。 現在,您需要將每個ID首次出現在已排序列表中。
這樣的事情怎么樣?
using System;
using System.Collections.Generic;
using System.Linq;
public class Person
{
public int ID;
public string Name;
public DateTime ChangeDate;
}
public class PersonComparer : IEqualityComparer<Person>
{
public bool Equals(Person p1, Person p2)
{
return p1.ID == p2.ID;
}
public int GetHashCode(Person p)
{
return p.ID.GetHashCode();
}
}
class Program
{
static void Main(string[] args)
{
var list1 = new List<Person>
{
new Person { ID = 1, Name = "Peter", ChangeDate = DateTime.Parse("2011-10-21") },
new Person { ID = 2, Name = "John", ChangeDate = DateTime.Parse("2011-10-22") },
new Person { ID = 3, Name = "Mike", ChangeDate = DateTime.Parse("2011-10-23") },
new Person { ID = 4, Name = "Dave", ChangeDate = DateTime.Parse("2011-10-24") }
};
var list2 = new List<Person>
{
new Person { ID = 1, Name = "Pete", ChangeDate = DateTime.Parse("2011-10-21") },
new Person { ID = 2, Name = "Johny", ChangeDate = DateTime.Parse("2011-10-20") },
new Person { ID = 3, Name = "Mikey", ChangeDate = DateTime.Parse("2011-10-24") },
new Person { ID = 5, Name = "Larry", ChangeDate = DateTime.Parse("2011-10-27") }
};
var pc = new PersonComparer();
var combined = list1.Join(list2, p => p.ID, p => p.ID, (p1,p2) => p2.ChangeDate > p1.ChangeDate ? p2 : p1)
.Union(list1.Except(list2, pc))
.Union(list2.Except(list1, pc));
foreach(var p in combined)
{
Console.WriteLine(p.ID + " " + p.Name + " " + p.ChangeDate);
}
}
}
您可以對其進行串聯和排序,然后獲得不同的值:
class PersonIdEqualityComparer : IEqualityComparer<Person>
{
public bool Equals(Person x, Person y)
{
return x.ID == y.ID;
}
public int GetHashCode(Person person)
{
return person.ID;
}
}
var result = list1.Concat(list2)
.OrderByDescending(i => DateTime.Parse(i.ChangeDate)) // Most recent first
.Distinct(new PersonIdEqualityComparer())
;
假設Distinct
將從每個集合中取出遇到的第一個項目,而不是一個任意項目。 考慮到它可能只是在遍歷集合時將它們插入到HashSet
,這對我來說似乎很合理。
它還不進行錯誤檢查。 如果任何值可以為null,或者ChangeDate
無效,則此代碼將引發異常。 如果這可能是一個問題,建議您在傳遞數據之前檢查數據,並在PersonIdEqualityComparer
類中進行錯誤檢查。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.