在C#中产生两个列表项的集合差异
Produce the set difference of two List Items in C#
我有 2 个可用列表。我需要收集不再使用的数据。
例如
列表 1:
- 1
- 2
- 3
- 4
- 5
列表 2:
- 1
- 2
- 4
- 5
- 6
结果数据集需要。
列表 2 中未包含的项目:
- 3
我希望使用类似以下内容的东西:
var itemsNotInList2 = List2.Except(List1).ToList();
你在这个例子中处理 List<int>
那么你的想法是正确的,只是 args 颠倒了。应该是;
var itemsNotInList2 = List1.Except(List2).ToList();
想一想如何用通俗易懂的英语表达这一点。要获得 itemsNotInList2
,我想获取 List1
中的所有内容,除了 List2
中的内容。您在问题中的代码为您提供 List2
但不在 List1
中的项目,其中有 none 因为 List2
是 List1
[ 的子集=28=]
请注意,这种方法通常不适合引用类型,因为默认的 comaparer 会比较引用本身。为了对对象进行类似的操作,您必须实现 IEqualityComparer
并调用接受它作为第三个参数的重载。例如,如果您正在处理 List<Person>
而 Person
有一个 public string Ssid
,您可以定义 Equal
和 return p1.Ssid == p2.Ssid
并将其用作比较的基础。如果需要,您可以在 msdn 上找到这方面的示例。
public class Person
{
public string Ssid;
// other properties and methods
}
public class PersonSsidEqualityComparer : IEqualityComparer<Person>
{
public bool Equal(Person lhs, Person rhs)
{
return lhs.Ssid == rhs.Ssid
}
public int GetHashCode(Person p)
{
return p.Value.GetHashCode();
}
}
现举例说明;
List<Person> people = new List<Person>();
List<Person> otherPeople = new List<Person>();
Person p1 = new Person("123"); // pretend this constructor takes an ssid
Person p2 = new Person("123");
Person p3 = new Person("124");
Person p4 = p1;
现在一些使用我上面设置的数据的例子;
people.Add(p1);
people.Add(p3);
otherPeople.Add(p2);
var ThemPeople = people.Except(otherPeople);
// gives you p1 and p3
var ThemOtherPeople = people.Except(otherPeople, new PersonSsidEqualityComparar());
// only gives you p3
otherPeople.Add(p4);
var DoingReferenceComparesNow = people.Except(otherPeople);
// gives you only p3 cause p1 == p4 (they're the same address)
试试这个
var itemsNotInList2 = List1.Except(List2).ToList();
如果您要比较对象,您可能应该提供自己的 Equality Comparer。
例如:
public class YourClass
{
public int Value;
}
public class YourClassEqualityComparer : IEqualityComparer<YourClass>
{
public bool Equals(YourClass x, YourClass y)
{
return x.Value == y.Value;
}
public int GetHashCode(YourClass obj)
{
return obj.Value.GetHashCode();
}
}
因此您可以使用 Except 的重载,它采用相等比较器的实例:
var list = l1.Except(l2, new YourClassEqualityComparer());
我有 2 个可用列表。我需要收集不再使用的数据。
例如
列表 1:
- 1
- 2
- 3
- 4
- 5
列表 2:
- 1
- 2
- 4
- 5
- 6
结果数据集需要。
列表 2 中未包含的项目:
- 3
我希望使用类似以下内容的东西:
var itemsNotInList2 = List2.Except(List1).ToList();
你在这个例子中处理 List<int>
那么你的想法是正确的,只是 args 颠倒了。应该是;
var itemsNotInList2 = List1.Except(List2).ToList();
想一想如何用通俗易懂的英语表达这一点。要获得 itemsNotInList2
,我想获取 List1
中的所有内容,除了 List2
中的内容。您在问题中的代码为您提供 List2
但不在 List1
中的项目,其中有 none 因为 List2
是 List1
[ 的子集=28=]
请注意,这种方法通常不适合引用类型,因为默认的 comaparer 会比较引用本身。为了对对象进行类似的操作,您必须实现 IEqualityComparer
并调用接受它作为第三个参数的重载。例如,如果您正在处理 List<Person>
而 Person
有一个 public string Ssid
,您可以定义 Equal
和 return p1.Ssid == p2.Ssid
并将其用作比较的基础。如果需要,您可以在 msdn 上找到这方面的示例。
public class Person
{
public string Ssid;
// other properties and methods
}
public class PersonSsidEqualityComparer : IEqualityComparer<Person>
{
public bool Equal(Person lhs, Person rhs)
{
return lhs.Ssid == rhs.Ssid
}
public int GetHashCode(Person p)
{
return p.Value.GetHashCode();
}
}
现举例说明;
List<Person> people = new List<Person>();
List<Person> otherPeople = new List<Person>();
Person p1 = new Person("123"); // pretend this constructor takes an ssid
Person p2 = new Person("123");
Person p3 = new Person("124");
Person p4 = p1;
现在一些使用我上面设置的数据的例子;
people.Add(p1);
people.Add(p3);
otherPeople.Add(p2);
var ThemPeople = people.Except(otherPeople);
// gives you p1 and p3
var ThemOtherPeople = people.Except(otherPeople, new PersonSsidEqualityComparar());
// only gives you p3
otherPeople.Add(p4);
var DoingReferenceComparesNow = people.Except(otherPeople);
// gives you only p3 cause p1 == p4 (they're the same address)
试试这个
var itemsNotInList2 = List1.Except(List2).ToList();
如果您要比较对象,您可能应该提供自己的 Equality Comparer。
例如:
public class YourClass
{
public int Value;
}
public class YourClassEqualityComparer : IEqualityComparer<YourClass>
{
public bool Equals(YourClass x, YourClass y)
{
return x.Value == y.Value;
}
public int GetHashCode(YourClass obj)
{
return obj.Value.GetHashCode();
}
}
因此您可以使用 Except 的重载,它采用相等比较器的实例:
var list = l1.Except(l2, new YourClassEqualityComparer());