两个列表之间的差异
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了两个列表之间的差异相关的知识,希望对你有一定的参考价值。
我有两个填充了CustomsObjects的通用列表。
我需要在第三个列表中检索这两个列表(第一个没有第二个项目的项目)之间的差异。
我在想使用.Except()
是一个好主意,但我不知道如何使用这个..帮助!
使用Except
是正确的方法。如果你的类型覆盖Equals
和GetHashCode
,或者你只对引用类型相等感兴趣(即两个引用只有“相等”,如果它们引用完全相同的对象),你可以使用:
var list3 = list1.Except(list2).ToList();
如果你需要表达一种自定义的平等观念,例如通过ID,你需要实现IEqualityComparer<T>
。例如:
public class IdComparer : IEqualityComparer<CustomObject>
{
public int GetHashCode(CustomObject co)
{
if (co == null)
{
return 0;
}
return co.Id.GetHashCode();
}
public bool Equals(CustomObject x1, CustomObject x2)
{
if (object.ReferenceEquals(x1, x2))
{
return true;
}
if (object.ReferenceEquals(x1, null) ||
object.ReferenceEquals(x2, null))
{
return false;
}
return x1.Id == x2.Id;
}
}
然后使用:
var list3 = list1.Except(list2, new IdComparer()).ToList();
请注意,这将删除任何重复的元素。如果你需要保留重复项,最简单的方法是从list2
创建一个集合并使用类似的东西:
var list3 = list1.Where(x => !set2.Contains(x)).ToList();
如果两个列表都实现IEnumerable接口,则可以使用LINQ实现此目的。
list3 = list1.where(i => !list2.contains(i));
List<int> list1 = new List<int>();
List<int> list2 = new List<int>();
List<int> listDifference = new List<int>();
foreach (var item1 in list1)
{
foreach (var item2 in list2)
{
if (item1 != item2)
listDifference.Add(item1);
}
}
List<ObjectC> _list_DF_BW_ANB = new List<ObjectC>();
List<ObjectA> _listA = new List<ObjectA>();
List<ObjectB> _listB = new List<ObjectB>();
foreach (var itemB in _listB )
{
var flat = 0;
foreach(var itemA in _listA )
{
if(itemA.ProductId==itemB.ProductId)
{
flat = 1;
break;
}
}
if (flat == 0)
{
_list_DF_BW_ANB.Add(itemB);
}
}
你可以这样做:
var result = customlist.Where(p => !otherlist.Any(l => p.someproperty == l.someproperty));
我认为重要的是要强调 - 使用Except method将返回第一个没有第二个项目的物品。它不会返回第二个没有出现的元素。
var list1 = new List<int> { 1, 2, 3, 4, 5};
var list2 = new List<int> { 3, 4, 5, 6, 7 };
var list3 = list1.Except(list2).ToList(); //list3 contains only 1, 2
但如果你想在两个列表之间得到真正的区别:
第一个中没有项目的第一个项目和第二个项目中没有项目的项目。
您需要使用Except两次:
var list1 = new List<int> { 1, 2, 3, 4, 5};
var list2 = new List<int> { 3, 4, 5, 6, 7 };
var list3 = list1.Except(list2); //list3 contains only 1, 2
var list4 = list2.Except(list1); //list4 contains only 6, 7
var resultList = list3.Concat(list4).ToList(); //resultList contains 1, 2, 6, 7
或者你可以使用HashSet的SymmetricExceptWith方法。但它改变了调用的集合:
var list1 = new List<int> { 1, 2, 3, 4, 5};
var list2 = new List<int> { 3, 4, 5, 6, 7 };
var list1Set = list1.ToHashSet(); //.net framework 4.7.2 and .net core 2.0 and above otherwise new HashSet(list1)
list1Set.SymmetricExceptWith(list2);
var resultList = list1Set.ToList(); //resultList contains 1, 2, 6, 7
var third = first.Except(second);
(如果你不喜欢引用懒惰的集合,你也可以在ToList()
之后调用Except()
。)
如果要比较的值是基本数据类型,Except()
方法使用默认比较器比较值,例如int
,string
,decimal
等。
否则,将通过对象地址进行比较,这可能不是您想要的...在这种情况下,让您的自定义对象实现IComparable
(或实现自定义IEqualityComparer
并将其传递给Except()
方法)。
由于Except扩展方法在两个IEumebles上运行,因此在我看来它将是一个O(n ^ 2)操作。如果性能是一个问题(如果你的列表很大),我建议从list1创建一个HashSet并使用HashSet的ExceptWith方法。
有点晚了但这里有适合我的解决方案
var myBaseProperty = (typeof(BaseClass)).GetProperties();//get base code properties
var allProperty = entity.GetProperties()[0].DeclaringType.GetProperties();//get derived class property plus base code as it is derived from it
var declaredClassProperties = allProperty.Where(x => !myBaseProperty.Any(l => l.Name == x.Name)).ToList();//get the difference
在上面提到的代码中,我得到了我的基类和派生类列表之间的属性差异
(LINQ)(C#)此示例显示如何使用LINQ比较两个字符串列表,并输出names1.txt中但不在names2.txt中的.Except()行。
// Create the IEnumerable data sources.
string[] names1 = System.IO.File.ReadAllLines(@"../../../names1.txt");
string[] names2 = System.IO.File.ReadAllLines(@"../../../names2.txt");
// Create the query. Note that method syntax must be used here.
IEnumerable<string> differenceQuery = names1.Except(names2);
// Execute the query.
Console.WriteLine("The following lines are in names1.txt but not names2.txt");
foreach (string s in differenceQuery)
Console.WriteLine(s);
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit");
Console.ReadKey();
var list3 = list1.Where(x => !list2.Any(z => z.Id == x.Id)).toList();
注意:list3
将包含不在两个列表中的项目或对象。
var resultList = checklist.Where(p => myList.All(l => p.value != l.value)).ToList();
以上是关于两个列表之间的差异的主要内容,如果未能解决你的问题,请参考以下文章