是否有更好的方法将列表中的对象转换为按日期并排显示

问题描述 投票:0回答:1

我想重新组织对象列表,并按并排视图中的输入日期对它们进行分类,以便我可以按天比较不同工具的交易。 所以这个视图需要重新组织 from

如下

我创建的唯一逻辑是使用发电机对象字典。然而,它迫使我每次都定义列。有没有更有效的方法?

linqpad 分享中的代码。 linqpad 分享

void Main()
{
    List<STSmyTrade> testoj = new List<STSmyTrade>(); // object 1
    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();

     


    // need to compare the 2 instruments sorted by date

    Dictionary<DateTime, ExpandoObject> analysiscompare = new Dictionary<DateTime, ExpandoObject>();
    foreach (STSmyTrade t in  testoj ) // loop first time comparing before and after
    {
        dynamic eo;
        if (!analysiscompare.Keys.Contains(t.entryTime.Date))// if i dont have a record in the dictionary object, create it.
        
        {
            eo = new ExpandoObject();
             eo.day=t.entryTime.Date.ToString("yyyy-MM-dd");// just assign the day.
            eo.eurusdentryTime = null;
            eo.eurusdentryPrice = null;
            eo.audusdentryTime = null;
            eo.audusdentryPrice = null;
            analysiscompare.Add(t.entryTime.Date, eo);

        }
        //dynamic 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; }
    
}

我可以完成这项工作的唯一方法是创建一个映射到每个唯一对象(audusd、eurusd)的自定义列。然而,这是不可扩展的。

c# linqpad
1个回答
0
投票

假设上课:

class STSmyTrade
{
    public string instrument;
    public decimal entryPrice;
    public DateTime entryTime;
}

我们为结果创建一个新类:

class SideBySideEntry
{
    public DateOnly day;
    public TimeOnly? eurUsdTime, audUsdTime;
    public decimal? eurUsdPrice, audUsdPrice;
}

我们可以使用对象和集合初始化器来初始化测试:

var testoj = new List<STSmyTrade> {
    new() {
        instrument = "eurusd",
        entryPrice = 3,
        entryTime = DateTime.Now.AddDays(1)
    },
    new() {
        instrument = "eurusd",
        entryPrice = 6,
        entryTime = DateTime.Now.AddDays(2)
    },
    new() {
        instrument = "audusd",
        entryPrice = 3,
        entryTime = DateTime.Now
    },
    new() {
        instrument = "audusd",
        entryPrice = 6,
        entryTime = DateTime.Now.AddDays(2)
    }
};

我们可以使用 LINQ 和一些模式匹配来转换这样的条目:

var sideBySideList = testoj
    .GroupBy(x => DateOnly.FromDateTime(x.entryTime))
    .Select(g => new SideBySideEntry {
        day = g.Key,
        eurUsdTime = g.FirstOrDefault(e => e.instrument == "eurusd")
            is { entryTime: var dt } ? TimeOnly.FromDateTime(dt) : null,
        eurUsdPrice = g.FirstOrDefault(e => e.instrument == "eurusd")?.entryPrice,
        audUsdTime = g.FirstOrDefault(e => e.instrument == "audusd")
            is { entryTime: var dt2 } ? TimeOnly.FromDateTime(dt2) : null,
        audUsdPrice = g.FirstOrDefault(e => e.instrument == "audusd")?.entryPrice,
    })
    .OrderBy(x => x.day)
    .ToList();

此控制台测试...

foreach (var e in sideBySideList) {
    Console.WriteLine($"{e.day} | {e.eurUsdTime,8} | {e.eurUsdPrice,8:n2} | {e.audUsdTime,8} | {e.audUsdPrice,8:n2}");
}

...产生以下输出:

30.12.2023 |          |          |    18:05 |     3.00
31.12.2023 |    18:05 |     3.00 |          |
01.01.2024 |    18:05 |     6.00 |    18:05 |     6.00
© www.soinside.com 2019 - 2024. All rights reserved.