如何使用C# Lambda合并单个列表并生成指定匿名类型
实现按Key分组并合并Flag对应的字符串
针对你的需求,我们可以通过两种方式实现:更直观的GroupBy方法,以及你提到的GroupJoin方法,下面分别演示:
先回顾你的基础代码
首先是你定义的类和填充的数据:
public class MyData { public int Key { get; set; } public string MyString { get; set; } public bool MyFlag { get; set; } } var data = new List<MyData> { new MyData() { Key = 1, MyFlag = true, MyString = "Hello" }, new MyData() { Key = 1, MyFlag = false, MyString = "Goodbye" }, new MyData() { Key = 2, MyFlag = true, MyString = "Test" }, new MyData() { Key = 2, MyFlag = false, MyString = "Merge" }, new MyData() { Key = 3, MyFlag = false, MyString = "Data" } };
方法一:使用GroupBy(推荐,更简洁)
这种方式直接按Key分组,然后在每个组内分别提取MyFlag=true和MyFlag=false对应的字符串,不存在的情况用空字符串填充:
var result = data.GroupBy(item => item.Key) .Select(group => new { Key = group.Key, TrueString = group.FirstOrDefault(x => x.MyFlag == true)?.MyString ?? string.Empty, FalseString = group.FirstOrDefault(x => x.MyFlag == false)?.MyString ?? string.Empty }) .ToList();
代码解释:
GroupBy(item => item.Key):将所有MyData对象按Key值分组,相同Key的项会被分到同一组中。Select中创建匿名类型:TrueString:从组内找到第一个MyFlag=true的项,提取它的MyString;如果没有这样的项,就返回空字符串(?? string.Empty处理null情况)。FalseString:同理,提取组内MyFlag=false的字符串。
运行后得到的结果完全符合你的需求:
| Key | TrueString | FalseString |
|---|---|---|
| 1 | Hello | Goodbye |
| 2 | Test | Merge |
| 3 | Data |
方法二:使用GroupJoin
GroupJoin通常用于关联两个不同的集合,这里我们可以先把原列表拆分为两个子集(MyFlag=true和MyFlag=false),再用GroupJoin按Key关联,最后补充上只有false的条目:
// 拆分出两个子集 var trueItems = data.Where(x => x.MyFlag == true); var falseItems = data.Where(x => x.MyFlag == false); // 使用GroupJoin关联两个子集 var resultWithGroupJoin = trueItems.GroupJoin( falseItems, trueItem => trueItem.Key, // 第一个集合的关联键 falseItem => falseItem.Key, // 第二个集合的关联键 (trueItem, matchedFalseItems) => new { Key = trueItem.Key, TrueString = trueItem.MyString, FalseString = matchedFalseItems.FirstOrDefault()?.MyString ?? string.Empty }) // 补充只有MyFlag=false的条目(比如Key=3) .Union( falseItems.Where(f => !trueItems.Any(t => t.Key == f.Key)) .Select(f => new { Key = f.Key, TrueString = string.Empty, FalseString = f.MyString }) ) // 按Key排序,保证顺序和原数据一致 .OrderBy(x => x.Key) .ToList();
代码解释:
- 先拆分出
trueItems和falseItems两个子集,分别存储MyFlag为true和false的项。 GroupJoin将trueItems和falseItems按Key关联,每个trueItem会对应一组匹配的falseItems,我们取这组里的第一个项的字符串。- 因为
GroupJoin只会包含存在于trueItems中的Key,所以需要用Union补充那些只有falseItems的Key(比如示例中的Key=3)。 - 最后用
OrderBy保证结果按Key升序排列。
两种方法都能得到你想要的结果,如果你只是处理单集合的分组需求,GroupBy会更简洁易用;如果是多集合关联场景,GroupJoin会更合适。
内容的提问来源于stack exchange,提问作者user10780967
相关产品推荐
相关产品推荐

