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

如何实现基于动态表达式对List<dynamic>进行分组?

实现动态表达式分组的GenerateGroup方法

我来帮你搞定这个支持动态表达式列表分组的方法,核心思路是把每个传入的表达式编译成可执行的委托,然后用所有表达式的结果组合成唯一的分组键,再基于这个键对集合进行分组。

方法实现代码

首先是GenerateGroup方法的完整实现,它接受List<dynamic>数据源和任意数量的分组表达式:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

public static class GroupHelper
{
    public static IEnumerable<IGrouping<object, dynamic>> GenerateGroup(List<dynamic> source, params Expression<Func<dynamic, object>>[] groupExpressions)
    {
        // 先把所有表达式编译成可直接调用的委托,提升运行效率
        var compiledSelectors = groupExpressions.Select(expr => expr.Compile()).ToList();

        // 按组合键分组:用匿名类型包装所有表达式的结果,自动实现相等性判断
        return source.GroupBy(item => 
        {
            var keyValues = compiledSelectors.Select(selector => selector(item)).ToList();
            return new { Keys = keyValues };
        });
    }
}

关键逻辑说明

  • 表达式编译:Expression<Func<>>是表达式树,需要调用Compile()转换成委托才能执行,这样可以高效获取每个dynamic元素的属性值。
  • 分组键设计:用匿名类型包装所有表达式的结果,C#编译器会自动为匿名类型生成Equals和GetHashCode方法,基于内部属性的值进行判断,完美适配分组的键相等性要求。
  • dynamic兼容性:因为是dynamic类型,只要数据源中的元素包含表达式指定的属性(比如Test、Test2),运行时就能正常获取值;如果元素缺少对应属性,会抛出RuntimeBinderException,可以根据需要添加异常处理逻辑。

调用示例

假设你的数据源是这样的:

var data = new List<dynamic>
{
    new { Test = "GroupA", Test2 = "Value1" },
    new { Test = "GroupA", Test2 = "Value1" },
    new { Test = "GroupB", Test2 = "Value2" },
    new { Test = "GroupB", Test2 = "Value2" },
    new { Test = "GroupA", Test2 = "Value1" }
};

调用GenerateGroup方法并遍历分组结果:

var groups = GroupHelper.GenerateGroup(data, x => x.Test, x => x.Test2);

foreach (var group in groups)
{
    Console.WriteLine($"分组键: {string.Join(", ", group.Key.Keys)}");
    foreach (var item in group)
    {
        Console.WriteLine($"  元素: Test={item.Test}, Test2={item.Test2}");
    }
}

运行后会得到2个分组,正好符合你的需求——相同Test和Test2组合的元素会被分到同一组。

可选优化

如果你的表达式数量是固定的,也可以用ValueTuple作为分组键,性能会更优:

// 比如固定2个表达式的情况
return source.GroupBy(item => (selector1(item), selector2(item)));

但如果表达式数量是动态传入的,用匿名类型包装列表的方式更灵活。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:30:13