C# 获取两个列表之间的差异
我有两个列表(C# 获取两个列表之间的差异,c#,.net,linq,C#,.net,Linq,我有两个列表(ListA和ListB),这些列表的类型是相同的PersonInfo,Login字段是唯一的键 public class PersonInfo { public string Login { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public int Age { get; set; } public bool
ListA
和ListB
),这些列表的类型是相同的PersonInfo
,Login
字段是唯一的键
public class PersonInfo
{
public string Login { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public bool Active { get; set; }
}
我想比较一下这两个列表:
ListA
中获得ListB
中不可用的项目列表ListA
(Login
字段是唯一的键)获取两个列表之间存在差异的项目的列表ListA
中的Login
“MyLogin”,则FirstName
的值与ListB
中的值不匹配。“MyLogin”为登录名的项目必须是结果列表的一部分
示例:如果特定登录名的ListA
和ListB
之间的Age
不同,则该项必须是结果的一部分
谢谢。编辑
请尝试此解决方案以了解细节差异:
-使用默认相等比较器比较值,生成两个序列的集合差
double[] numbers1 = { 2.0, 2.1, 2.2, 2.3, 2.4, 2.5 };
double[] numbers2 = { 2.2 };
IEnumerable<double> onlyInFirstSet = numbers1.Except(numbers2);
您可以使用LINQ中的Zip()和Intersect()来比较自定义数据类型列表的对象,您需要在类中实现
IEquatable
,并重写GetHashCode()
检查这个
你们班
public class PersonInfo : IEquatable<PersonInfo>
{
public string Login { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public bool Active { get; set; }
public bool Equals(PersonInfo other)
{
//Check whether the compared object is null.
if (Object.ReferenceEquals(other, null)) return false;
//Check whether the compared object references the same data.
if (Object.ReferenceEquals(this, other)) return true;
//Check whether the properties are equal.
return Login.Equals(other.Login) && FirstName.Equals(other.FirstName) && LastName.Equals(other.LastName) && Age.Equals(other.Age) && Active.Equals(other.Active);
}
public override int GetHashCode()
{
int hashLogin = Login == null ? 0 : Login.GetHashCode();
int hashFirstName = FirstName == null ? 0 : FirstName.GetHashCode();
int hashLastName = LastName == null ? 0 : LastName.GetHashCode();
int hashAge = Age.GetHashCode();
int hashActive = Active.GetHashCode();
//Calculate the hash code.
return (hashLogin + hashFirstName + hashLastName) ^ (hashAge + hashActive);
}
}
公共类PersonInfo:IEquatable
{
公共字符串登录{get;set;}
公共字符串名{get;set;}
公共字符串LastName{get;set;}
公共整数{get;set;}
公共bool活动{get;set;}
公共布尔等于(PersonInfo其他)
{
//检查比较对象是否为空。
if(Object.ReferenceEquals(other,null))返回false;
//检查比较对象是否引用相同的数据。
if(Object.ReferenceEquals(this,other))返回true;
//检查属性是否相等。
返回Login.Equals(other.Login)&&FirstName.Equals(other.FirstName)&&LastName.Equals(other.LastName)&&Age.Equals(other.Age)&&Active.Equals(other.Active);
}
公共覆盖int GetHashCode()
{
int hashLogin=Login==null?0:Login.GetHashCode();
int hashFirstName=FirstName==null?0:FirstName.GetHashCode();
int hashLastName=LastName==null?0:LastName.GetHashCode();
int hashAge=Age.GetHashCode();
int hashActive=Active.GetHashCode();
//计算散列码。
返回(hashLogin+hashFirstName+hashLastName)^(hashAge+hashActive);
}
}
下面是您如何使用它(如Pranay的回复中所列)
List List a=new List(){new PersonInfo{Login=“1”,FirstName=“James”,LastName=“Watson”,Active=true,Age=21},new PersonInfo{Login=“2”,FirstName=“Jane”,LastName=“Morrison”,Active=true,Age=25},new PersonInfo{Login=“3”,FirstName=“Kim”,LastName=“John”,Active=false,Age=33};
List ListB=new List(){new PersonInfo{Login=“1”,FirstName=“James2222”,LastName=“Watson”,Active=true,Age=21},new PersonInfo{Login=“3”,FirstName=“Kim”,LastName=“John”,Active=false,Age=33};
//获取ListA中不在ListB中的项
List FilteredListA=ListA.Except(ListB.ToList();
//获取ListA和FilteredListA之间的差异(FilteredListA中的项目将从ListA中删除)
RemoveAll(a=>FilteredListA.Contains(a));
尝试此方法进行对象比较,并在列表中循环
publicstaticvoid GetPropertyChanges(这个T oldObj,T newObj)
{
类型=类型(T);
foreach(type.GetProperties中的System.Reflection.PropertyInfo pi(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance))
{
对象selfValue=type.GetProperty(pi.Name).GetValue(oldObj,null);
objecttovalue=type.GetProperty(pi.Name).GetValue(newObj,null);
if(selfValue!=null&&toValue!=null)
{
if(selfValue.ToString()!=toValue.ToString())
{
//做你的代码
}
}
}
}
无论如何,我都会得到我想要的结果。1.如果ListA有3个项目,ListB有2个项目,那么在结果中我看不到缺少的项目。2.如果两个列表中都有3个项目(两侧的登录匹配),如何比较每个属性?(RemoveAll未出现在intellisense中)抱歉,但结果中仍有3项,而不是difference@Kris-我-嗨,检查我的编辑答案粘贴的链接…去那个链接有答案帮助你获得细节差异。。。
var compare1to2 = from a in
from b in driveList2.Where(b => b.property == a.property).DefaultIfEmpty()
select a;
public class PersonInfo : IEquatable<PersonInfo>
{
public string Login { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public bool Active { get; set; }
public bool Equals(PersonInfo other)
{
//Check whether the compared object is null.
if (Object.ReferenceEquals(other, null)) return false;
//Check whether the compared object references the same data.
if (Object.ReferenceEquals(this, other)) return true;
//Check whether the properties are equal.
return Login.Equals(other.Login) && FirstName.Equals(other.FirstName) && LastName.Equals(other.LastName) && Age.Equals(other.Age) && Active.Equals(other.Active);
}
public override int GetHashCode()
{
int hashLogin = Login == null ? 0 : Login.GetHashCode();
int hashFirstName = FirstName == null ? 0 : FirstName.GetHashCode();
int hashLastName = LastName == null ? 0 : LastName.GetHashCode();
int hashAge = Age.GetHashCode();
int hashActive = Active.GetHashCode();
//Calculate the hash code.
return (hashLogin + hashFirstName + hashLastName) ^ (hashAge + hashActive);
}
}
List<PersonInfo> ListA = new List<PersonInfo>() { new PersonInfo { Login = "1", FirstName = "James", LastName = "Watson", Active = true, Age = 21 }, new PersonInfo { Login = "2", FirstName = "Jane", LastName = "Morrison", Active = true, Age = 25 }, new PersonInfo { Login = "3", FirstName = "Kim", LastName = "John", Active = false, Age = 33 } };
List<PersonInfo> ListB = new List<PersonInfo>() { new PersonInfo { Login = "1", FirstName = "James2222", LastName = "Watson", Active = true, Age = 21 }, new PersonInfo { Login = "3", FirstName = "Kim", LastName = "John", Active = false, Age = 33 } };
//Get Items in ListA that are not in ListB
List<PersonInfo> FilteredListA = ListA.Except(ListB).ToList();
//To get the difference between ListA and FilteredListA (items from FilteredListA will be removed from ListA)
ListA.RemoveAll(a => FilteredListA.Contains(a));
var list3 = list1.Except(list2).ToList(); //List3 contains what in list1 but not _list2.
public static void GetPropertyChanges<T>(this T oldObj, T newObj)
{
Type type = typeof(T);
foreach (System.Reflection.PropertyInfo pi in type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance))
{
object selfValue = type.GetProperty(pi.Name).GetValue(oldObj, null);
object toValue = type.GetProperty(pi.Name).GetValue(newObj, null);
if (selfValue != null && toValue != null)
{
if (selfValue.ToString() != toValue.ToString())
{
//do your code
}
}
}
}