LINQ 按许多值分组
Posted
技术标签:
【中文标题】LINQ 按许多值分组【英文标题】:LINQ group by many values 【发布时间】:2021-07-25 10:39:43 【问题描述】:我有多个 MyObject
实例,它们需要按它们的类型 MyType
分组(每个对象很多)。只需要每种类型的最新对象(由MyObject.Date
定义)。
以下代码通过嵌套的 foreach 语句实现了这一目标。
IEnumerable<MyObject> objects = ...;
var grouped = new Dictionary<MyType, MyObject>();
foreach (MyObject obj in objects.OrderBy(x => x.Date))
foreach (MyType type in obj.Types)
grouped[type] = obj;
如何使用GroupBy
使用LINQ 方法语法重写它?
【问题讨论】:
你的问题很难理解。 似乎您想要的是生成多个分组,即为每个可能的MyType
值进行一个分组(而不是单个组,其中每个分组代表@987654328 的某种组合@ 值)。如果是这样,您应该能够简单地将可能的MyType
值的集合投影到基于每个这些值的分组中。 您尝试过什么?请修正您的问题,使其包含正确的minimal reproducible example,并详细说明该代码的作用、与您想要的有何不同以及...
...具体您需要什么帮助。还请确保您的描述是明确的(请注意,对输入和预期输出的详细解释有助于提供这种澄清,这是当前版本的问题所缺乏的)。
@peter-duniho 如果我的问题无法理解,我很抱歉。你是对的,我想为每个包含的 MyType
值生成一个分组。提供的代码已经实现了第一段中概述的目标,但我想知道如何使用 LINQ GroupBy
而不是嵌套的 foreach 语句来编写它。
【参考方案1】:
首先,您需要升级您的MyType
对象(如果您还没有这样做的话)以覆盖GetHashCode
和Equals
。如果不这样做,您不能将引用类型用作字典的键,否则它只会在内存中按引用分组。
这是我的你MyType
:
public class MyType
public int Id;
public override int GetHashCode()
return this.Id.GetHashCode();
public override bool Equals(object obj)
if (obj is MyType other)
return other.Id == this.Id;
return base.Equals(obj);
接下来,我们需要一些示例数据来处理:
IEnumerable<MyObject> objects = new[]
new MyObject()
Date = new DateTime(1969, 7, 20),
Types = new List<MyType>()
new MyType() Id = 1 ,
new MyType() Id = 2 ,
,
new MyObject()
Date = new DateTime(1986, 4, 26),
Types = new List<MyType>()
new MyType() Id = 2 ,
new MyType() Id = 3 ,
,
;
现在,很简单:
var query =
from obj in objects
orderby obj.Date descending
from type in obj.Types
group obj by type into gts
from gt in gts.Take(1)
select new
type = gts.Key,
obj = gt
;
Dictionary<MyType, MyObject> grouped =
query
.ToDictionary(x => x.type, x => x.obj);
这给了我:
在方法语法中,查询变为:
Dictionary<MyType, MyObject> grouped =
objects
.OrderByDescending(obj => obj.Date)
.SelectMany(obj => obj.Types, (obj, type) => new obj, type )
.GroupBy(x => x.type, x => x.obj)
.SelectMany(gts => gts.Take(1), (gts, gt) => new type = gts.Key, obj = gt )
.ToDictionary(x => x.type, x => x.obj);
【讨论】:
感谢您的回答!这绝对是解决方案,但我对查询语法并不熟悉。也可以写成方法语法吗? @morrow - 是的,它可以。查询语法只是每种情况下方法语法的语法糖。我当然知道我更喜欢查询语法。 非常感谢您的出色回答!我会尝试更多地了解查询语法。以上是关于LINQ 按许多值分组的主要内容,如果未能解决你的问题,请参考以下文章