我有三个User
列表:
ICollection<User> listOne = _somewhere.GetUsers(1);
ICollection<User> listTwo = _somewhere.GetUsers(2);
ICollection<User> listThree = _somewhere.GetUsers(3);
要比较的“唯一”标识符是名为“电子邮件”的字符串字段。
如何从三个中获得一个唯一的列表(例如没有欺骗)。
在使用Except
之前,我有一个来自两个列表的唯一列表,但不确定如何使用三个?我是否必须在前两个使用Except
,然后在前两个和第三个的结果上再次使用它?
另外,我应该提及用户列表来自外部Web API调用,并且无法保证每个列表都有唯一的电子邮件地址列表。
所以我需要两个步骤:
答案 0 :(得分:4)
您可以在列表中合并列表并执行重复数据删除(使用Distinct()
)。
var uniqueList = listOne.Union(listTwo)
.Union(listThree)
.Distinct(new EmailComparer())
.ToList();
比较器可以这么简单:
class EmailComparer : IEqualityComparer<User>
{
public bool Equals(User x, User y)
{
return x.Email == y.Email;
}
public int GetHashCode(User obj)
{
return obj.Email.GetHashCode();
}
}
修改:
如果我们将自定义电子邮件比较器应用于Distinct()
,则不需要在评论Union()
中指出:
var emailComparer = new EmailComparer();
var uniqueList = listOne.Union(listTwo, emailComparer)
.Union(listThree, emailComparer)
.ToList();
答案 1 :(得分:3)
如果您从具有相同电子邮件的用户列表中选择哪个用户并不重要,您可以这样做:
var res = listOne.Concat(listTwo).Concat(listThree)
.GroupBy(u => u.Email)
.Select(g => g.First());
同样,这假设当电子邮件地址相同时,您选择的用户无关紧要。
答案 2 :(得分:2)
首先定义我们如何定义唯一性:
private class EmailEqComparer : IEqualityComparer<User>
{
public bool Equals(User x, User y)
{
//don't bother shortcutting on reference equality, since if they come from
//separate web-calls it's unlikely to happen, though it could
//with some optimisations on the web-client code.
if(x == null)
return y == null;
if(y == null)
return false;
return x.Email == y.Email;
}
public int GetHashCode(User obj)
{
return obj == null ? 0 : obj.Email.GetHashCode();
}
}
现在在每个项目上调用Distinct
,并将结果放入列表中:
var distinctUnion = listOne.Concat(listTwo).Concat(listThree).Distinct(new EmailEqComparer());