【问题标题】:LINQ GroupBy x where there is more then one x and y is uniqueLINQ GroupBy x 其中有多个 x 并且 y 是唯一的
【发布时间】:2013-01-09 15:23:52
【问题描述】:

假设有这样的对象:

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 相同且不止一个的 foos。

 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

【问题讨论】:

标签: c# linq linq-to-objects


【解决方案1】:

快到了!

bar.GroupBy(f => f.x)
   .Where(g => g.Select(f => f.y).Distinct().Skip(1).Any())
   .ToList();

g.Select(f =&gt; f.y).Distinct().Count() 表示“从组中的foos 中获取所有y 值,丢弃所有重复项,然后然后计算它们”。

编辑.Skip(1).Any().Count() &gt; 1 更好,因为它一旦找到第二个项目就会停止查找,而不是找到一百万然后去 a million &gt; 1。通常我第一次就做对了……

(请注意,您的结果不是foos 的列表,而是foos 组的列表,其中每个组都有一个常量x。)

【讨论】:

    【解决方案2】:

    试试这个:

    bar
      .GroupBy(a => a.x)
      .Where(a => a.Count() > 1 && a.Any(b=>b.y != a.First().y))
      .ToList();
    

    【讨论】:

    • 您的解决方案有效,但 Rawling 的速度稍快一些。平均 30 毫秒。
    猜你喜欢
    • 1970-01-01
    • 2014-02-17
    • 2011-04-18
    • 2020-08-12
    • 1970-01-01
    • 2013-04-22
    • 1970-01-01
    • 1970-01-01
    • 2021-05-30
    相关资源
    最近更新 更多