2017-06-06 4 views
-1

私はをまず四半期でレコードをソートしようとしているコレクションを持っていますし、四半期の中で最高額であるをソートしようとしています。私はそれが最初にソートされあるOrderByの後にOrderByDescendingを実行するにはどうすればよいですか?

enter image description here

からOrderBy(o=>o.Quater).OrderByDescending(o=>o.Amount)出力の変更を行う場合は

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

であるように私のコードは、これまでのところです四半期別に、次に金額で計算します。

しかし、私はを探しています。クォーターと四半期内の最初の並べ替えは、金額 降順です。

所望の出力は、目標を達成してプログラムで変更する必要がある何

enter image description here

のですか?

事前に感謝します。

+1

あなたはタイプミスがあります。クォーターではなくクォーターです。 –

+2

2番目のOrderByをThenByに変更します。 google for "Enumerable ThenBy" https://msdn.microsoft.com/en-us/library/bb534743%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396 –

答えて

1

で出力を確認することができます単数でソートする必要はありませんeプロパティのみ。並べ替えフィールドは匿名オブジェクトタプルとして返すことができます。

C#7で次のように記述することができます:以前のバージョンでは

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

を:

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() 
+0

最初の部分は間違っています - 匿名型でソートします。コンパイラは匿名型の値の等価性を実装しますが、比較は実装しません。 –

+0

@IvanStoevあなたは正しいです。しかし、古いものと新しいものの両方のタプルで動作します。 –

10

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

ThenByDescending

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

を置き換えるには、指定された比較を使用して降順に 配列内の要素のその後の順序付けを行います。ここで

3

あなたは(あなたが最初のソート結果の上に第2の並べ替えを実行したいならば、あなたはThenByDescendingの使用をしなければならない、あなただけの、最終的なソートの出力を得ている、リストを2回ソートされていますあなたは降順で第二の並べ替えをしたいか、他ThenBy()を使用している場合)[並べ替えが続くこのようなとして:私はthis exampleにここにコードを変更した

var sortedItems = lstTest.OrderBy(o=>o.Quater).ThenByDescending(o=>o.Amount); 

、あなたはあなたはフィドル

関連する問題