Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何拆分列表<;T>;分为两个列表,一个包含所有重复值,另一个包含剩余值?_C#_Linq_List_Duplicates - Fatal编程技术网

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));