IEnumerable.Intersect 不 return 所有匹配的值
IEnumerable.Intersect does not return all values that match
我有两个列表List<MyClass>
:
public class MyClass : IEquatable<MyClass>
{
public string AccountNumber { get; set; }
public int ID { get; set; }
public int AccountType { get; set; }
public bool Equals(MyClass other)
{
if (other == null) return false;
if (object.ReferenceEquals(this, other))
return true;
return AccountNumber.Equals(other.AccountNumber) && AccountType.Equals(other.AccountType);
}
public override int GetHashCode()
{
int hashAccountNumber = AccountNumber == null ? 0 : AccountNumber.GetHashCode();
int hashType = AccountType.GetHashCode();
return hashAccountNumber ^ hashType;
}
}
如果我使用下面的代码
var list1 = new List<MyClass>()
{
new MyClass() { AccountNumber = "1", AccountType = 1, ID = 1},
new MyClass() { AccountNumber = "1", AccountType = 1, ID = 2},
new MyClass() { AccountNumber = "2", AccountType = 1, ID = 3},
new MyClass() { AccountNumber = "3", AccountType = 1, ID = 4}
};
var list2 = new List<MyClass>()
{
new MyClass() { AccountNumber = "1", AccountType = 1, ID = 1 }
};
var alist = list1.Intersect(list2).ToList();
alist
只有 1 个元素 MyClass.ID == 1
。它不 return 第二个也匹配。我也可以反过来做 var alist = list2.Intersect(list1).ToList();
我得到相同的结果
我的 IEquatable
实现有问题吗?因为我不确定我做错了什么。或者这只是 IEnumerable
的工作方式?我可以使用另一种方法 return list1 中的所有匹配元素吗?我真的希望有:)
交集是一个set操作(set理解为数据结构!),所以,我不明白为什么你的结果应该包含相同的项目两次。集合是唯一元素的集合。
来自MSDN:
When the object returned by this method is enumerated, Intersect enumerates first, collecting all distinct elements of that sequence. It then enumerates second, marking those elements that occur in both sequences. Finally, the marked elements are yielded in the order in which they were collected.
正如其他人已经说过的那样,Intersect
将始终 return 两个集合中 不同 元素的列表。
要实现您想要的效果,请尝试将 Intersect
更改为:
var alist = list1.Where(x => list2.Contains(x)).ToList();
试试这个,使用这段代码你的 Equals 方法不会被浪费:
var alist = list1.Where(m => list2.Any(n => n.Equals(m)));
我有两个列表List<MyClass>
:
public class MyClass : IEquatable<MyClass>
{
public string AccountNumber { get; set; }
public int ID { get; set; }
public int AccountType { get; set; }
public bool Equals(MyClass other)
{
if (other == null) return false;
if (object.ReferenceEquals(this, other))
return true;
return AccountNumber.Equals(other.AccountNumber) && AccountType.Equals(other.AccountType);
}
public override int GetHashCode()
{
int hashAccountNumber = AccountNumber == null ? 0 : AccountNumber.GetHashCode();
int hashType = AccountType.GetHashCode();
return hashAccountNumber ^ hashType;
}
}
如果我使用下面的代码
var list1 = new List<MyClass>()
{
new MyClass() { AccountNumber = "1", AccountType = 1, ID = 1},
new MyClass() { AccountNumber = "1", AccountType = 1, ID = 2},
new MyClass() { AccountNumber = "2", AccountType = 1, ID = 3},
new MyClass() { AccountNumber = "3", AccountType = 1, ID = 4}
};
var list2 = new List<MyClass>()
{
new MyClass() { AccountNumber = "1", AccountType = 1, ID = 1 }
};
var alist = list1.Intersect(list2).ToList();
alist
只有 1 个元素 MyClass.ID == 1
。它不 return 第二个也匹配。我也可以反过来做 var alist = list2.Intersect(list1).ToList();
我得到相同的结果
我的 IEquatable
实现有问题吗?因为我不确定我做错了什么。或者这只是 IEnumerable
的工作方式?我可以使用另一种方法 return list1 中的所有匹配元素吗?我真的希望有:)
交集是一个set操作(set理解为数据结构!),所以,我不明白为什么你的结果应该包含相同的项目两次。集合是唯一元素的集合。
来自MSDN:
When the object returned by this method is enumerated, Intersect enumerates first, collecting all distinct elements of that sequence. It then enumerates second, marking those elements that occur in both sequences. Finally, the marked elements are yielded in the order in which they were collected.
正如其他人已经说过的那样,Intersect
将始终 return 两个集合中 不同 元素的列表。
要实现您想要的效果,请尝试将 Intersect
更改为:
var alist = list1.Where(x => list2.Contains(x)).ToList();
试试这个,使用这段代码你的 Equals 方法不会被浪费:
var alist = list1.Where(m => list2.Any(n => n.Equals(m)));