我有一个帐户的基本类(为简洁而删除了其他属性):
public class Account
{
public string Email { get; set; }
}
我有List<T>
个这样的帐户。
我可以轻松删除基于电子邮件地址的重复项:
var uniques = list.GroupBy(x => x.Email).Select(x => x.First()).ToList();
名为&#39; uniques&#39;现在只包含基于电子邮件地址的每个帐户中的一个,任何重复的都被丢弃。
我想做一些不同的事情并将列表分成两部分 一个列表仅包含&#39; true&#39;唯一值,另一个列表将包含所有重复项。
例如以下帐户电子邮件列表:
unique@email.com
dupe@email.com
dupe@email.com
将分为两个列表:
唯一
unique@email.com重复
dupe@email.com
dupe@email.com
我已经能够通过使用顶部的示例创建唯一值列表来实现此目的。然后我在原始列表中使用.Except()
来获取重复的差异。最后,我可以将每个副本循环到&#39; pop&#39;它出自唯一列表并将其移至重复列表。
Here is a working example on .NET Fiddle
我可以用更高效或符合语法的方式拆分列表吗?
如果有必要,我很乐意使用第三方图书馆,但我宁愿坚持使用纯粹的LINQ。
我知道CodeReview,但觉得问题也适合这里。
答案 0 :(得分:6)
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();
groups[0]
将是唯一的,group[1]
将是非唯一的。
答案 1 :(得分:3)
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);
或者,一旦获得一个列表,您可以使用Except
获取另一个列表:
var uniques = list.Except(duplicates);
// or
var duplicates = list.Except(uniques);
答案 2 :(得分:0)
另一种方法是获取唯一身份,然后对于重复项,只需获取原始列表中不属于唯一身份的元素。
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));