设置如下对象:
class foo
{
public String x{ get; set; }
public String y{ get; set; }
}
var bar = new List<foo> {
new foo{ x= "u", y= "w"},
new foo{ x= "s", y= "q"},
new foo{ x= "u", y= "r" },
new foo{ x= "1", y= "0" },
new foo{ x= "1", y= "0" },
};
我想把这些x相同但y不同的分组。
这将得到x相同且多于一个的foo。
bar.GroupBy(x => x.x).Where(x => x.Count() > 1).ToList();
结果如下:
foo{ x= "u", y= "w"}
foo{ x= "u", y= "r" }
foo{ x= "1", y= "0" }
foo{ x= "1", y= "0" }
这是我想要得到的:
foo{ x= "u", y= "w"}
foo{ x= "u", y= "r" }
那么我如何过滤掉y相同的元素呢?
在bar中有3,999,996个对象,这三个都可以正常工作。
bar.GroupBy(f => f.x).Where(a => a.Select(f => f.y).Distinct().Skip(1).Any()).ToList(); // Elapsed ms = 702,715,779,666 AVG = 715
bar.GroupBy(f => f.x).Where(a => a.Count() > 1 && a.Any(b => b.y!= a.First().y)).ToList(); // Elapsed ms = 753,701,728,749 AVG = 732
bar.GroupBy(f => f.x).Where(a => a.Skip(1).Any() && a.Any(b => b.y!= a.First().y)).ToList(); // Elapsed ms = 734,751,758,745 AVG = 747
快到了!
bar.GroupBy(f => f.x)
.Where(g => g.Select(f => f.y).Distinct().Skip(1).Any())
.ToList();
g.Select(f => f.y).Distinct().Count()
表示"从组中的foo
s中获取所有y
值,丢弃任何重复的,然后然后计数"。
Edit: .Skip(1).Any()
比.Count() > 1
好,因为它在找到第二个项目时立即停止查找,而不是找到一百万个然后转到a million > 1
。通常我第一次就做对了…
(请注意,您的结果不是foo
s的列表,它是foo
s组的列表,其中每个组都有一个常数x
。)
试试这个:
bar
.GroupBy(a => a.x)
.Where(a => a.Count() > 1 && a.Any(b=>b.y != a.First().y))
.ToList();