C# 如何拆分列表<;T>;分为两个列表,一个包含所有重复值,另一个包含剩余值?
我有一个帐户的基本类(为简洁起见删除了其他属性): 我有这些账户的C# 如何拆分列表<;T>;分为两个列表,一个包含所有重复值,另一个包含剩余值?,c#,linq,list,duplicates,C#,Linq,List,Duplicates,我有一个帐户的基本类(为简洁起见删除了其他属性): 我有这些账户的列表 我可以根据电子邮件地址轻松删除重复项: var uniques = list.GroupBy(x => x.Email).Select(x => x.First()).ToList(); 根据电子邮件地址,名为“uniques”的列表现在只包含每个帐户中的一个,任何重复的帐户都将被丢弃 我想做一些不同的事情,将列表一分为二。 一个列表将只包含“true”唯一值,另一个列表将包含所有重复项 例如,以下帐户电子邮件
列表
我可以根据电子邮件地址轻松删除重复项:
var uniques = list.GroupBy(x => x.Email).Select(x => x.First()).ToList();
根据电子邮件地址,名为“uniques”的列表现在只包含每个帐户中的一个,任何重复的帐户都将被丢弃
我想做一些不同的事情,将列表一分为二。
一个列表将只包含“true”唯一值,另一个列表将包含所有重复项
例如,以下帐户电子邮件列表:
unique@email.com
dupe@email.com
dupe@email.com
将分为两个列表:
独特的
unique@email.com
重复项
dupe@email.com
dupe@email.com
通过使用顶部的示例创建一个独特值列表,我已经能够实现这一点。然后,我在原始列表上使用.Except()
,以获得重复的差异。最后,我可以循环每个副本,将其从唯一列表中“弹出”并移动到副本列表中
我可以用一种更有效的或语法上更甜的方式拆分列表吗?
如果有必要,我很乐意使用第三方库,但我宁愿只使用纯LINQ。
我知道CodeReview,但觉得这个问题也适合这里
var duplicates = list.GroupBy(x => x) // or x.Property if you are grouping by some property.
.Where(g => g.Count() > 1)
.SelectMany(g => g);
var uniques = list.GroupBy(x => x) // or x.Property if you are grouping by some property.
.Where(g => g.Count() == 1)
.SelectMany(g => g);
或者,获得一个列表后,可以使用获取另一个列表,但除外:
var uniques = list.Except(duplicates);
// or
var duplicates = list.Except(uniques);
组[0]
将是唯一的,而组[1]
将是非唯一的。另一种方法是获取唯一性,然后对于重复项,只需获取原始列表中不在唯一性中的元素即可
IEnumerable<Account> uniques;
IEnumerable<Account> dupes;
dupes = list.Where(d =>
!(uniques = list.GroupBy(x => x.Email)
.Where(g => g.Count() == 1)
.SelectMany(u => u))
.Contains(d));
IEnumerable unique;
无数次的重复;
重复=列表。其中(d=>
!(uniques=list.GroupBy(x=>x.Email)
.其中(g=>g.Count()==1)
.SelectMany(u=>u))
.包含(d));
这似乎并没有指定它是基于帐户的Email
属性的。呃,我是个白痴。道歉。这真是太棒了,谢谢。除了(重复的)
给你唯一的吗?请注意,我没有尝试过,因此这里可能有一些细微差别,我遗漏了。@LasseV.Karlsen:返回相同的结果。您可以使用.GroupBy(g=>g.Count==1)
和groups[true]
将是唯一的,groups[false]
重复的。@JacobKrall否仍然是groups[0]
和groups[1]
除非您使用ToDictionary
而不是ToList
。另外,我不喜欢先查找哪个(对还是错),所以我只是将其显式化。这很公平。虽然--Count
不存在,但它不会编译(使用LINQ扩展方法Count()
,并且SelectMany()
不是有效的重载,您必须传递一个selector@JacobKrall谢谢,修好了。
var groups = list.GroupBy(x => x.Email)
.GroupBy(g => g.Count() == 1 ? 0 : 1)
.OrderBy(g => g.Key)
.Select(g => g.SelectMany(x => x))
.ToList();
IEnumerable<Account> uniques;
IEnumerable<Account> dupes;
dupes = list.Where(d =>
!(uniques = list.GroupBy(x => x.Email)
.Where(g => g.Count() == 1)
.SelectMany(u => u))
.Contains(d));