You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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();

代码解释:

  1. GroupBy(item => item.Key):将所有MyData对象按Key值分组,相同Key的项会被分到同一组中。
  2. Select中创建匿名类型:
    • TrueString:从组内找到第一个MyFlag=true的项,提取它的MyString;如果没有这样的项,就返回空字符串(?? string.Empty处理null情况)。
    • FalseString:同理,提取组内MyFlag=false的字符串。

运行后得到的结果完全符合你的需求:

KeyTrueStringFalseString
1HelloGoodbye
2TestMerge
3Data

方法二:使用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();

代码解释:

  1. 先拆分出trueItems和falseItems两个子集,分别存储MyFlag为true和false的项。
  2. GroupJoin将trueItems和falseItems按Key关联,每个trueItem会对应一组匹配的falseItems,我们取这组里的第一个项的字符串。
  3. 因为GroupJoin只会包含存在于trueItems中的Key,所以需要用Union补充那些只有falseItems的Key(比如示例中的Key=3)。
  4. 最后用OrderBy保证结果按Key升序排列。

两种方法都能得到你想要的结果,如果你只是处理单集合的分组需求,GroupBy会更简洁易用;如果是多集合关联场景,GroupJoin会更合适。

内容的提问来源于stack exchange,提问作者user10780967

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:07:52