如何执行OrderBy,然后执行OrderByDescending?

时间:2017-06-06 06:27:01

标签: c# linq sorting lambda

我有一个集合,我试图按季度排序记录,然后在季度内按最高金额排序。到目前为止我的代码是:

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

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Test> lstTest = new List<Test>();
            lstTest.Add(new Test { dt = new DateTime(2017, 1, 2), amount = 2500 });
            lstTest.Add(new Test { dt = new DateTime(2017, 1, 2), amount = 10000 });
            lstTest.Add(new Test { dt = new DateTime(2017, 1, 5), amount = 4000 });
            lstTest.Add(new Test { dt = new DateTime(2017, 1, 10), amount = 40000 });
            lstTest.Add(new Test { dt = new DateTime(2017, 1, 15), amount = 2000 });
            lstTest.Add(new Test { dt = new DateTime(2017, 1, 25), amount = 12000 });
            lstTest.Add(new Test { dt = new DateTime(2017, 2, 5), amount = 38000 });
            lstTest.Add(new Test { dt = new DateTime(2017, 2, 10), amount = 38000 });
            lstTest.Add(new Test { dt = new DateTime(2017, 2, 15), amount = 4000 });
            lstTest.Add(new Test { dt = new DateTime(2017, 2, 20), amount = 2000 });
            lstTest.Add(new Test { dt = new DateTime(2017, 2, 20), amount = 20000 });
            lstTest.Add(new Test { dt = new DateTime(2017, 3, 15), amount = 2000 });
            lstTest.Add(new Test { dt = new DateTime(2017, 3, 20), amount = 2000 });
            lstTest.Add(new Test { dt = new DateTime(2017, 3, 20), amount = 4000 });
            lstTest.Add(new Test { dt = new DateTime(2017, 3, 31), amount = 1000 });
            lstTest.Add(new Test { dt = new DateTime(2017, 4, 9), amount = 50000 });
            lstTest.Add(new Test { dt = new DateTime(2017, 4, 11), amount = 2000 });
            lstTest.Add(new Test { dt = new DateTime(2017, 4, 21), amount = 1000 });
            lstTest.Add(new Test { dt = new DateTime(2017, 4, 21), amount = 10000 });
            lstTest.Add(new Test { dt = new DateTime(2017, 4, 28), amount = 5000 });
            lstTest.Add(new Test { dt = new DateTime(2017, 5, 5), amount = 45000 });
            lstTest.Add(new Test { dt = new DateTime(2017, 5, 7), amount = 98000 });
            lstTest.Add(new Test { dt = new DateTime(2017, 5, 9), amount = 7000 });
            lstTest.Add(new Test { dt = new DateTime(2017, 5, 25), amount = 2000 });
            lstTest.Add(new Test { dt = new DateTime(2017, 5, 31), amount = 1000 });

            var result = lstTest.Select(x => new
            {
                Amount = x.amount,
                Date = x.dt,
                MonthDiff = GetMonthsDiff(DateTime.Now, x.dt),
                Quater = GetQuarter(DateTime.Now, x.dt)
            }).OrderBy(o=>o.Quater).ToList();

            foreach (var res in result)
            {
                Console.WriteLine("Amount = {0}  Date= {1} MonthDiff= {2}  Quater= {3}", res.Amount, res.Date, res.MonthDiff, res.Quater);
            }
            Console.ReadKey();
        }


        public static string GetQuarter(DateTime start, DateTime end)// int month)
        {
            int month = GetMonthsDiff(start, end);
            string quarter =  month <= 3 ? "Q1" : (month >= 4 && month <= 6) ? "Q2" : (month >= 7 && month <= 9) ? "Q3" : "Q4";
            return quarter;
        }



        public static int GetMonthsDiff(DateTime start, DateTime end)
        {
            if (start > end)
                return GetMonthsDiff(end, start);

            int months = 0;
            do
            {
                start = start.AddMonths(1);
                if (start > end)
                    return months;

                months++;
            }
            while (true);
        }
    }

    public class Test
    {
        public DateTime dt { get; set; }
        public int amount { get; set; }
    }
}

输出

enter image description here

如果我OrderBy(o=>o.Quater).OrderByDescending(o=>o.Amount)输出更改为

enter image description here

那是它首先按季度排序,然后按金额排序。

但我正在寻找按季度进行首次排序,并按季度排序按金额递减

所需的输出是

enter image description here

需要在程序中修改哪些内容以实现目标?

3 个答案:

答案 0 :(得分:10)

替换

OrderBy(o=>o.Quater).OrderByDescending(o=>o.Amount)

OrderBy(o=>o.Quater).ThenByDescending(o=>o.Amount)
  

ThenByDescending执行a中元素的后续排序   使用指定的比较器按降序排列。

答案 1 :(得分:3)

在这里,您要对列表进行两次排序,您只获得最终排序的输出,如果您想对第一个排序结果执行第二次排序,那么您必须使用ThenByDescending (如果你想按降序排列第二种,或者使用from model import Person ),接着是OrderBy,如下所示:

ThenBy()

我在this example修改了代码,你可以检查小提琴中的输出

答案 2 :(得分:1)

您不需要仅按单个属性进行排序。您可以将排序字段作为匿名对象元组返回。

在C#7中你可以写:

OrderBy(o => Tuple.Create(o.Quarter,o.Amount));

在以前的版本中:

OrderBy(o=>o.Quarter).ThenByDescending(o=>o.Amount);

如果要使用不同的排序顺序,则必须一次指定一个字段,例如:

var result = ( from x in lstTest
               let o = new {
                            Amount = x.amount,
                            Date = x.dt,
                            MonthDiff = GetMonthsDiff(DateTime.Now, x.dt),
                            Quarter = GetQuarter(DateTime.Now, x.dt)
                          }
               orderby o.Quarter, o.Amount descending
               select o
             ).ToList()

或者您可以使用查询语法来使代码更清晰:

$(window).click(function(event) {
  if ($(event.target).closest('div#mySidenav').length === 0 && $(event.target).closest('.menu-icon').length === 0) {
    closeNav()
  }
})