【问题标题】:Simplifying linq when filtering data过滤数据时简化 linq
【发布时间】:2013-08-20 15:47:04
【问题描述】:

我想就如何简化下面的 foreach 块征求意见。我试图在一个 linq 语句中完成所有操作,但我无法弄清楚如何在查询中操作“计数”值。

有关我要实现的目标的更多详细信息: - 我有一个包含潜在重复项的巨大列表,其中 Id 重复,但属性“计数”是不同的数字 - 我想摆脱重复,但仍然不丢失那些“计数”值 - 所以对于具有相同 ID 的项目,我总结了“计数”属性

不过,当前的代码看起来并不漂亮:

var grouped = bigList.GroupBy(c => c.Id).ToList();
foreach (var items in grouped)
{
    var count = 0;
    items.Each(c=> count += c.Count);
    items.First().Count = count;
}
var filtered =  grouped.Select(y => y.First());

我不指望整个解决方案,一些想法也会受到高度赞赏:)

【问题讨论】:

  • FWIW ReSharper 擅长将 foreach 代码转换为等效的 LINQ 语句。
  • 绝对推荐尝试 resharper eval
  • 您可能可以取消 .ToList() 并只使用返回的 IEnumerable;这种方式可能更快,因为枚举不是由 .ToList()

标签: c# .net linq


【解决方案1】:

鉴于你正在改变集合,我个人会用计数制作一个新的“项目”:

var results = bigList.GroupBy(c => c.Id)
                     .Select(g => new Item(g.Key, g.Sum(i => i.Count)))
                     .ToList();

这将执行从原始到具有正确 IdCount 值的 Item 实例的新集合的简单映射。

【讨论】:

  • 很抱歉,您的Item 可能缺少更多信息,例如原来的不只有IdCount,它可能有比这更多的属性和OP想要包含/保留所有属性?我们可以使用constructor 来创建原始类型的新实例,但是 OP 没有显示原始类型,所以它被卡住了。
  • @KingKing 是的 - 这需要添加到构造中 - 不过,您应该始终能够通过构造函数(或对象初始化器)复制该对象。
  • 看起来不错!但正如@KingKing 提到的,你丢失了关于原始数据的所有信息,我仍然需要这些信息。
【解决方案2】:
var filtered = bigList.GroupBy(c=>c.Id)
                      .Select(g=> {
                                    var f = g.First();
                                    f.Count = g.Sum(c=>c.Count);
                                    return f;
                                  });

【讨论】:

  • 这基本上等同于原始数据 - 但在查询期间原始数据的突变似乎是错误的;)
  • @ReedCopsey:在看到您的评论之前,我很想 +1 KingKing 的回答。您可能需要编辑您的答案,以添加更多背景信息,说明您选择避免改变集合的原因。
  • @AndrewCoonce 我对这个答案做了 +1,但觉得我需要评论,所以至少知道这确实会导致原始数据发生突变。
  • 另外 - 意识到这将没有任何效果,除非你遍历它(即:使用 foreach 或在末尾添加 ToList()
  • @ReedCopsey 当然,我猜他可能想执行一些foreach 然后打印信息。
猜你喜欢
  • 1970-01-01
  • 2012-07-12
  • 2020-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多