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

如何高效将List对象按日期转换为多交易工具并排对比视图?

问题描述

我需要将STSmyTrade对象列表按entryTime日期重组,生成并排视图来按日对比不同交易工具(如eurusd、audusd)的交易数据,要把现有列表视图转换成目标并排视图。目前我用Dictionary<DateTime, ExpandoObject>实现,但需要手动为每个交易工具定义entryTime和entryPrice列,这个方案扩展性很差。有没有更高效的实现方式?

示例代码

void Main()
{
    List<STSmyTrade> testoj = new List<STSmyTrade>(); 
    STSmyTrade a1 = new STSmyTrade();
    a1.instrument = "eurusd";
    a1.entryPrice = 3;
    a1.entryTime = DateTime.Now.AddDays(1);
    testoj.Add(a1);
    
    STSmyTrade a2 = new STSmyTrade();
    a2.instrument = "eurusd";
    a2.entryPrice = 6;
    a2.entryTime = DateTime.Now.AddDays(2);
    testoj.Add(a2);
    
    STSmyTrade a3 = new STSmyTrade();
    a3.instrument = "audusd";
    a3.entryPrice = 3;
    a3.entryTime = DateTime.Now;
    testoj.Add(a3);
    
    STSmyTrade a4 = new STSmyTrade();
    a4.instrument = "audusd";
    a4.entryPrice = 6;
    a4.entryTime = DateTime.Now.AddDays(2);
    testoj.Add(a4);
    testoj.Dump();

    // 按日期对比两种交易工具
    Dictionary<DateTime, ExpandoObject> analysiscompare = new Dictionary<DateTime, ExpandoObject>();
    foreach (STSmyTrade t in testoj ) 
    {
        dynamic eo;
        if (!analysiscompare.ContainsKey(t.entryTime.Date))
        {
            eo = new ExpandoObject();
            eo.day = t.entryTime.Date.ToString("yyyy-MM-dd");
            eo.eurusdentryTime = null;
            eo.eurusdentryPrice = null;
            eo.audusdentryTime = null;
            eo.audusdentryPrice = null;
            analysiscompare.Add(t.entryTime.Date, eo);
        }
        eo = analysiscompare[t.entryTime.Date];
        switch (t.instrument)
        {
            case "eurusd":
                eo.eurusdentryTime = t.entryTime;
                eo.eurusdentryPrice = t.entryPrice;
                break;
            case "audusd":
                eo.audusdentryTime = t.entryTime;
                eo.audusdentryPrice = t.entryPrice;
                break;
        }
    }
    analysiscompare.Values.ToList().Dump("side_by_side_view");
}

class STSmyTrade
{
    public DateTime entryTime { get; set; }
    public string instrument { get; set; }
    public double entryPrice { get; set; }
}

解决方案

可以通过分组+动态属性自动生成的方式解决扩展性问题,核心思路是先按日期分组,再针对每个分组里的交易工具,动态为ExpandoObject添加对应属性,无需提前硬编码工具名称:

优化后的代码

void Main()
{
    List<STSmyTrade> testoj = new List<STSmyTrade>(); 
    // 初始化测试数据
    STSmyTrade a1 = new STSmyTrade { instrument = "eurusd", entryPrice = 3, entryTime = DateTime.Now.AddDays(1) };
    STSmyTrade a2 = new STSmyTrade { instrument = "eurusd", entryPrice = 6, entryTime = DateTime.Now.AddDays(2) };
    STSmyTrade a3 = new STSmyTrade { instrument = "audusd", entryPrice = 3, entryTime = DateTime.Now };
    STSmyTrade a4 = new STSmyTrade { instrument = "audusd", entryPrice = 6, entryTime = DateTime.Now.AddDays(2) };
    STSmyTrade a5 = new STSmyTrade { instrument = "gbpusd", entryPrice = 1.2, entryTime = DateTime.Now.AddDays(1) }; // 新增测试工具
    testoj.AddRange(new[] {a1,a2,a3,a4,a5});
    testoj.Dump();

    // 1. 获取所有不重复的交易工具
    var allInstruments = testoj.Select(t => t.instrument).Distinct().ToList();
    
    // 2. 按日期分组并排序
    var groupedByDate = testoj.GroupBy(t => t.entryTime.Date).OrderBy(g => g.Key);
    
    // 3. 生成并排视图数据
    var analysisCompare = new List<dynamic>();
    foreach (var dateGroup in groupedByDate)
    {
        dynamic eo = new ExpandoObject();
        var eoDict = (IDictionary<string, object>)eo;
        eoDict["day"] = dateGroup.Key.ToString("yyyy-MM-dd");
        
        // 初始化所有工具的属性为null
        foreach (var instrument in allInstruments)
        {
            eoDict[$"{instrument}entryTime"] = null;
            eoDict[$"{instrument}entryPrice"] = null;
        }
        
        // 填充当前日期下各工具的交易数据
        foreach (var trade in dateGroup)
        {
            eoDict[$"{trade.instrument}entryTime"] = trade.entryTime;
            eoDict[$"{trade.instrument}entryPrice"] = trade.entryPrice;
        }
        
        analysisCompare.Add(eo);
    }
    
    analysisCompare.Dump("动态生成的并排视图");
}

class STSmyTrade
{
    public DateTime entryTime { get; set; }
    public string instrument { get; set; }
    public double entryPrice { get; set; }
}

关键改进点

  • 自动识别交易工具:通过Distinct()获取所有存在的交易工具,无需手动添加新工具的属性
  • 动态属性赋值:利用IDictionary<string, object>操作ExpandoObject,避免硬编码switch分支
  • 简洁的分组逻辑:用Linq的GroupBy替代手动遍历字典,代码更易读维护
  • 高扩展性:新增交易工具(如示例中的gbpusd)时,无需修改任何属性定义代码,自动生成对应列

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 03:17:34