我有List<Demo>
public class Demo
{
public Demo()
{
}
public int Id { get; set; }
public string Name { get; set; }
public string Title { get; set; }
}
Id属性对于列表中的每个记录都是唯一的。
如何从原始List<Demo>
获取List<Demo>
,其中包含名称和标题相同的所有重复项。
到目前为止,我所做的只是一条记录:
List<Demo> demo = new List<Demo>();
demo.Add(new Demo()
{
Id = 1,
Name = "Demo",
Title = "A"
});
demo.Add(new Demo()
{
Id = 2,
Name = "Demo",
Title = "A"
});
demo.Add(new Demo()
{
Id = 3,
Name = "Demo",
Title = "A"
});
demo.Add(new Demo()
{
Id = 4,
Name = "Demo1",
Title = "A"
});
demo.Add(new Demo()
{
Id = 5,
Name = "Demo2",
Title = "A"
});
然后我在做:
var duplicates = demo.GroupBy(t => new { t.Name, t.Title })
.Where(t => t.Count() > 1)
.Select(g => g.Key).ToList();
从上面的例子中我得到一个List<Demo>
,前面有3个项目,其中id为1,2,3,因为名称和标题相同。
答案 0 :(得分:9)
听起来你所缺少的只是一个SelectMany
电话。目前,您正在创建所有相应的组并向下过滤到具有多个条目的组 - 但如果您需要单个平面列表,则需要将这些组展平回其元素:
var duplicates = demo
.GroupBy(t => new { t.Name, t.Title })
.Where(t => t.Count() > 1)
.SelectMany(x => x) // Flatten groups to a single sequence
.ToList();
请注意,此不表示结果列表中的每个条目都具有相同的名称和标题。它确实意味着每个条目都有一个与至少一个其他条目共同的名称/标题组合。
答案 1 :(得分:2)
你快到了。
Groupby
将序列分组。每个小组都有一些共同点:小组的Key
。每个组都是一个序列,其中包含原始序列中与键匹配的所有元素。
您的密钥是new { t.Name, t.Title }
。您的原始序列将被分为具有相同名称/标题的对象组:
分组后的Where
会返回IGrouping
的序列。此序列仅包含一个元素:唯一具有多个元素的组。这是具有密钥演示/ A的组。
您的规范不是IGrouping的序列(其中每个组是Demo
的序列),而是Demo
的一个列表,其中包含所有具有重复名称/标题的元素。
这意味着您必须在Where
之后(在您的示例中此序列仅包含一个组)从所有组中获取元素,并将所有这些组连接成一个序列。这是由Enumerable.SelectMany
IEnumerable<Demo> duplicates = demo
.GroupBy(demoElement => new {demoElement.Name, demoElement.Title})
.Where(group => group.Skip(1).Any())
.SelectMany(group => group);
SelectMany
获取每个组的序列并将所有序列连接成一个序列。
顺便说一句,您是否注意到我没有使用Count()来检测是否有重复项,而是Skip(1).Any()
。如果你的一个组有数百个元素,那么在第一个元素之后停止计数就足够了。计算所有元素以检测是否存在多个元素是浪费计算能力。
最后一个提示:如果您不确定是否需要,请不要使用ToList()
。如果您的代码段的用户只想要第一个元素或前几个元素,那么如果您将所有元素计算到列表中,那将是一种浪费。尽可能长时间保持IEnumerable<Demo>
。
答案 2 :(得分:0)
如果你有超过1个标题并且名字相同,那么你想要的是什么。假设最后一个对象是Demo1
和A
。
var duplicates = demo.GroupBy(t => new { t.Name, t.Title }).Where(t => t.Count() > 1)
.Select(x => new { Count = x.Count(), Values = x.Select(y => y)})
.ToList();
这样做,为您提供计数和所有分组值(基于名称和标题)及其计数。
答案 3 :(得分:0)
下面的代码可以帮助您,
列出重复项= demo.GroupBy(grp =&gt; new {grp.Name,grp.Title})。SelectMany(selm =&gt; selm.Skip(1))。Distinct()。ToList();
根据您的预期答案,它正常运作。