C#lambda如何按子描述来排序列表

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

我有以下课程:

  public class Result
    {
        public string Description { get; set; }
        public DateTime StartTime { get; set; }
        public TimeSpan Elapsed { get; set; }
        public List<Result> Actions { get; set; }

    }

然后我按如下方式创建任务列表:

 List<Task<Result>> tasksToRun = new List<Task<Result>>();

然后将同时运行多个任务,并且在完成所有操作后,我想在文本框中打印结果。

现在,我循环执行任务并获得结果,并开始创建我的字符串生成器,然后开始工作

 foreach (var task in tasksToRun)
            {
                var result = task.Result;

                sb.Append(result.Description);
                sb.Append(Environment.NewLine);
                sb.Append(result.StartTime);
                sb.Append(Environment.NewLine);

                foreach(var action in result.Actions)
                {
                    elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
                        action.Elapsed.Hours, action.Elapsed.Minutes, action.Elapsed.Seconds,
                        action.Elapsed.Milliseconds / 10);
                    sb.Append("    -----------------  ");
                    sb.Append(Environment.NewLine);
                    sb.Append("    " + action.Description);
                    sb.Append(Environment.NewLine);
                    sb.Append("    " + elapsedTime);
                    sb.Append(Environment.NewLine);
                    sb.Append("    -----------------  ");
                }

                sb.Append(Environment.NewLine);

                elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
                        result.Elapsed.Hours, result.Elapsed.Minutes, result.Elapsed.Seconds,
                        result.Elapsed.Milliseconds / 10);

                sb.Append(elapsedTime);
                sb.Append(Environment.NewLine);
                sb.Append(Environment.NewLine);
                sb.Append(Environment.NewLine);

                txtResult.Text = sb.ToString();
            }

我的输出结果是:

Main
12/03/2020 11:09:31 a. m.
    -----------------  
    ValidateUser
    00:00:00.95
    -----------------      -----------------  
    GetInvoiceList
    00:00:12.73
    -----------------      -----------------  
    SearchFolio
    00:00:04.17
    -----------------      -----------------  
    SearchPatients
    00:00:06.12
    -----------------      -----------------  
    SearchOrganization
    00:00:08.60
    -----------------  
00:00:32.63


Main
12/03/2020 11:09:31 a. m.
    -----------------  
    ValidateUser
    00:00:00.49
    -----------------      -----------------  
    SearchFolio
    00:00:03.69
    -----------------      -----------------  
    GetInvoiceList
    00:00:10.15
    -----------------      -----------------  
    SearchOrganization
    00:00:00.55
    -----------------      -----------------  
    SearchPatients
    00:00:06.91
    -----------------  
00:00:21.85


Main
12/03/2020 11:09:31 a. m.
    -----------------  
    ValidateUser
    00:00:00.84
    -----------------      -----------------  
    SearchFolio
    00:00:07.29
    -----------------      -----------------  
    SearchOrganization
    00:00:05.99
    -----------------      -----------------  
    SearchPatients
    00:00:07.70
    -----------------      -----------------  
    GetInvoiceList
    00:00:10.45
    -----------------  
00:00:32.32

我想要打印为单独的选项的是一个子动作列表,并使用相同的描述进行汇总,所以我应该得到这样的内容:

 -----------------  
    ValidateUser
    00:00:00.95
    -----------------      -----------------  
    ValidateUser
    00:00:00.49
    -----------------      -----------------  
    ValidateUser
    00:00:00.84
    -----------------      -----------------  


    GetInvoiceList
    00:00:12.73
    -----------------      -----------------  
    GetInvoiceList
    00:00:10.15
    -----------------      -----------------  
    GetInvoiceList
    00:00:10.45
    -----------------      -----------------  


    SearchFolio
    00:00:04.17
    -----------------      -----------------  
    SearchFolio
    00:00:03.69
    -----------------      -----------------  
    SearchFolio
    00:00:07.29
    -----------------      -----------------  


    SearchPatients
    00:00:06.12
    -----------------      -----------------  
    SearchPatients
    00:00:06.91
    -----------------      -----------------  
    SearchPatients
    00:00:07.70
    -----------------      -----------------  


    SearchOrganization
    00:00:08.60
    -----------------  
    SearchOrganization
    00:00:00.55
    -----------------      -----------------
    SearchOrganization
    00:00:05.99
    -----------------      -----------------    

正在尝试这样:

tasksToRun.OrderBy(t=> t.Result.Actions.Descritpion)

但是因为Actions是一个列表,所以我无法直接获取Description属性。应该是一个简单的解决方案。

任何线索?

c# linq lambda
4个回答
0
投票

两个选项:

如果您假设每个动作只有一个不同的描述,则可以尝试以下操作:

tasksToRun.OrderBy(t=> t.Result.Actions.First().Descritpion)

如果每个动作都有许多不同的描述,则可以尝试以下方法:

tasksToRun.OrderBy(t=> t.Result.Actions.OrderBy(a => 
        a.Description).First().Descritpion)

然后,您将为每个动作排序所有描述,然后通过每个动作的第一个描述对整个列表进行排序。


0
投票

这是一个可行的例子。同时在调试窗口中输出enter image description here

public class Result
{
    public string Description { get; set; }
    public DateTime StartTime { get; set; }
    public TimeSpan Elapsed { get; set; }
    public List<Result> Actions { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        // Initialize some test data
        Result r1 = new Result()
        {
            Description = "Res1",
            StartTime = new DateTime(2020, 3, 1),
            Elapsed = new TimeSpan(12),
            Actions = new List<Result>() { }
        };
        Result r2 = new Result()
        {
            Description = "Res2",
            StartTime = new DateTime(2021, 3, 1),
            Elapsed = new TimeSpan(22),
            Actions = new List<Result>() { }
        };
        Result r3 = new Result()
        {
            Description = "Res3",
            StartTime = new DateTime(2022, 3, 1),
            Elapsed = new TimeSpan(3),
            Actions = new List<Result>() { }
        };

        List<Result> a1 = new List<Result>() { r1, r2, r3 };
        List<Result> a2 = new List<Result>() { r1, r2, r3 };
        List<Task<Result>> tasksToRun = new List<Task<Result>>();
        StringBuilder sb = new StringBuilder();

        Task<Result> t1 = Task<Result>.Factory.StartNew(() => new Result()
        {
            Description = "x1",
            StartTime = new DateTime(2020,2,2),
            Elapsed = new TimeSpan(2),
            Actions = a1
        });

        Task<Result> t2 = Task<Result>.Factory.StartNew(() => new Result()
        {
            Description = "x2",
            StartTime = DateTime.Now,
            Elapsed = new TimeSpan(33),
            Actions = a2
        });
        tasksToRun.Add(t1);
        tasksToRun.Add(t2);
        List<Result> holder = new List<Result>();

        // Run each tasks
        foreach (var task in tasksToRun)
        {
            var result = task.Result;
            foreach (var action in result.Actions)
            {
                holder.Add(action);
            }
        }

        // Re-arrange in the desired format
        string currentDesc = "";
        foreach (var action in holder.OrderBy(x => x.Description))
        {
            if(currentDesc != "" &&
                currentDesc != action.Description
              )
            {
                sb.Append(Environment.NewLine);
                sb.Append("********************");
            }

            var elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
                action.Elapsed.Hours, action.Elapsed.Minutes, action.Elapsed.Seconds,
                action.Elapsed.Milliseconds / 10);
            sb.Append("    -----------------  ");
            sb.Append(Environment.NewLine);
            sb.Append("    " + action.Description);
            sb.Append(Environment.NewLine);
            sb.Append("    " + elapsedTime);
            sb.Append(Environment.NewLine);
            sb.Append("    -----------------  ");
            currentDesc = action.Description;
        }

        var ss = sb.ToString();
    }
}

0
投票

使用Linq,您可以将每个Actions中的所有ResultSelectMany一起收集,然后按Description将它们分组以进行输出:

foreach (var actionTaskGroup in tasksToRun.SelectMany(t => t.Result.Actions).GroupBy(a => a.Description)) {
    foreach (var action in actionTaskGroup) {
        var elapsedTime = action.Elapsed.ToString(@"hh\:mm\:ss\.ff");
        sb.Append("    -----------------  \n");
        sb.Append($"    {action.Description}\n");
        sb.Append($"    {elapsedTime}\n");
        sb.Append("    -----------------  ");
    }

    sb.Append("    -----------------  \n");
    sb.Append(Environment.NewLine);
    sb.Append(Environment.NewLine);

    txtResult.Text = sb.ToString();
}

0
投票

给定一个名为List<Result>results,那么这是您需要做的关键部分:

    from result in results
    from action in result.Actions
    group action by action.Description into actions

这是我的完整代码,可以解决您的问题:

var results = new List<Result>()
{
    new Result()
    {
        Description = "Main",
        StartTime = new DateTime(2020, 3, 12, 11, 9, 31),
        Actions = new List<Result>()
        {
            new Result() { Description = "ValidateUser", Elapsed = TimeSpan.FromSeconds(0.95), },
            new Result() { Description = "GetInvoiceList", Elapsed = TimeSpan.FromSeconds(12.73), },
            new Result() { Description = "SearchFolio", Elapsed = TimeSpan.FromSeconds(4.17), },
            new Result() { Description = "SearchPatients", Elapsed = TimeSpan.FromSeconds(6.12), },
            new Result() { Description = "SearchOrganization", Elapsed = TimeSpan.FromSeconds(8.6), },
        }
    },
    new Result()
    {
        Description = "Main",
        StartTime = new DateTime(2020, 3, 12, 11, 9, 31),
        Actions = new List<Result>()
        {
            new Result() { Description = "ValidateUser", Elapsed = TimeSpan.FromSeconds(0.49), },
            new Result() { Description = "SearchFolio", Elapsed = TimeSpan.FromSeconds(3.69), },
            new Result() { Description = "GetInvoiceList", Elapsed = TimeSpan.FromSeconds(10.15), },
            new Result() { Description = "SearchOrganization", Elapsed = TimeSpan.FromSeconds(0.55), },
            new Result() { Description = "SearchPatients", Elapsed = TimeSpan.FromSeconds(6.91), },
        }
    },
    new Result()
    {
        Description = "Main",
        StartTime = new DateTime(2020, 3, 12, 11, 9, 31),
        Actions = new List<Result>()
        {
            new Result() { Description = "ValidateUser", Elapsed = TimeSpan.FromSeconds(0.84), },
            new Result() { Description = "SearchFolio", Elapsed = TimeSpan.FromSeconds(7.29), },
            new Result() { Description = "SearchOrganization", Elapsed = TimeSpan.FromSeconds(5.99), },
            new Result() { Description = "SearchPatients", Elapsed = TimeSpan.FromSeconds(7.70), },
            new Result() { Description = "GetInvoiceList", Elapsed = TimeSpan.FromSeconds(10.45), },
        }
    },
};

string ElaspedTime(TimeSpan elapsed) => $"{elapsed.Hours:00}:{elapsed.Minutes:00}:{elapsed.Seconds:00}.{(elapsed.Milliseconds / 10):00}";

var output1 =
    String.Join(
        Environment.NewLine + Environment.NewLine, 
        from result in results
        let header = new []
        {
            result.Description,
            result.StartTime.ToString(),
        }
        let details =
            result
                .Actions
                    .SelectMany(action => new[]
                    {
                        "-----------------",
                        action.Description,
                        ElaspedTime(action.Elapsed)
                    })
                    .Concat(new[] { "-----------------" })
                    .Select(x => $"    {x}")
        let tail = new[]
        {
            ElaspedTime(result.Actions.Select(x => x.Elapsed).Aggregate((x, y) => x.Add(y))),
        }
        select String.Join(Environment.NewLine, header.Concat(details).Concat(tail)));

var output2 =
    String.Join(
        Environment.NewLine + Environment.NewLine,
        from result in results
        from action in result.Actions
        group action by action.Description into actions
        let details =
            actions
                    .SelectMany(action => new[]
                    {
                        "-----------------",
                        action.Description,
                        ElaspedTime(action.Elapsed)
                    })
                    .Concat(new[] { "-----------------" })
                    .Select(x => $"    {x}")
        select String.Join(Environment.NewLine, details));

对于output1,我得到:

主要2020/03/12 11:09:31-----------------验证用户00:00:00.95-----------------GetInvoiceList00:00:12.73-----------------搜索作品集00:00:04.17-----------------搜索患者00:00:06.12-----------------搜索组织00:00:08.60-----------------00:00:32.57主要2020/03/12 11:09:31-----------------验证用户00:00:00.49-----------------搜索作品集00:00:03.69-----------------GetInvoiceList00:00:10.15-----------------搜索组织00:00:00.55-----------------搜索患者00:00:06.91-----------------00:00:21.79主要2020/03/12 11:09:31-----------------验证用户00:00:00.84-----------------搜索作品集00:00:07.29-----------------搜索组织00:00:05.99-----------------搜索患者00:00:07.70-----------------GetInvoiceList00:00:10.45-----------------00:00:32.27

对于output2,我得到:

-----------------验证用户00:00:00.95-----------------验证用户00:00:00.49-----------------验证用户00:00:00.84----------------------------------GetInvoiceList00:00:12.73-----------------GetInvoiceList00:00:10.15-----------------GetInvoiceList00:00:10.45----------------------------------搜索作品集00:00:04.17-----------------搜索作品集00:00:03.69-----------------搜索作品集00:00:07.29----------------------------------搜索患者00:00:06.12-----------------搜索患者00:00:06.91-----------------搜索患者00:00:07.70----------------------------------搜索组织00:00:08.60-----------------搜索组织00:00:00.55-----------------搜索组织00:00:05.99-----------------
© www.soinside.com 2019 - 2024. All rights reserved.