2011-07-01 8 views
0

私はASP.NET MVCメニュー用のクラスを作成しています。私はすべてのブログエントリのリストを取り、これに似たアーカイブメニューを作ることができるようにしたい:こここのリストの良い解決法がありますか?<DateTime>ソート?

1/2011 (2) 
3/2011 (1) 
4/2011 (12) 
etc... 

は、私が使用していますコードです:

public class ArchiveMenuModel 
{ 
    private List<ArchiveMenuItem> menuItems; 
    public List<ArchiveMenuItem> MenuItems { get { return menuItems; } } 

    public ArchiveMenuModel(List<DateTime> dates, string streamUrl) 
    { 
     menuItems = new List<ArchiveMenuItem>(); 
     int itemCount = 0; 
     dates = dates.OrderByDescending(x => x).ToList(); 

     for (int i=0; i<dates.Count; i++) 
     { 
      itemCount++; 
      if(i+1 < dates.Count) 
      { 
       if(!(dates[i].Month == dates[i + 1].Month && dates[i].Year == dates[i + 1].Year)) 
       { 
        menuItems.Add(new ArchiveMenuItem(streamUrl, dates[i].Month, dates[i].Year, itemCount)); 
        itemCount = 0; 
       } 
      } 
      else 
      { 
       menuItems.Add(new ArchiveMenuItem(streamUrl, dates[i].Month, dates[i].Year, itemCount)); 
      } 
     } 

    } 
} 

良い方法はありますおそらくLinqや何かを使って?具体的には、私は好きではない私のコードの一部は次のとおりです。

if(!(dates[i].Month == dates[i + 1].Month && dates[i].Year == dates[i + 1].Year)) 

文の場合、私は、このような醜いを避けることができれば、それは素晴らしいことです!

+0

は、LINQは、そこにありますか? ;-) [IEnumerable](http://msdn.microsoft.com/en-us/library/system.linq.enumerable.aspx)にある「OrderBy」と「GroupBy」を参照してください。後者はあなたのグループを取得し(各グループの要素を数えることができます)、前者はグループを注文します。 「派手なLINQ構文」で飾るか、通常のメソッド呼び出し(好きな方法)のままにしておきます。これは答えではありません。なぜなら、私はちょっとコードを叩くつもりはないからです。[LINQPad](http://linqpad.net)で少し遊んでお楽しみください! –

+0

私がそれをしようとしていたとき、私はエントリカウントを得るのが難しかった。また、 'GroupBy'は' DateTime'グループを月ではなく年で返しますが、時間ではありませんか? – quakkels

+0

空の月を含めますか?私。 "5/2011(0)"のような行? – svick

答えて

2
menuItems = dates 
    .GroupBy(x => new DateTime(x.Year, x.Month, 1)) 
    .Select(x=> new{Date = x.Key, Count = x.Count()}) 
    .OrderByDescending(x => x.Date) 
    .Select(x => new ArchiveMenuItem(streamUrl, 
             x.Date.Month, 
             x.Date.Year, 
             x.Count)) 
    .ToList(); 
+0

ニース!これも1つ働いている!ありがとうございました! – quakkels

-1

これらの線に沿って何か作業をする必要があります:

menuItems.GroupBy(x => x.Month + "/" + x.Year); 

を私は日時を保持しているプロパティの名前を知らないが、ITDは以下のように設定する必要があり、

menuItems.GroupBy(x => x.(datetime).Month + "/" + x.(datetime).Year); 
+0

'List dates' – quakkels

+0

なぜそれをする文字列を作成しますか? – svick

+0

グルーピングは正常に動作します。しかし、DateTimesのリストに正確に何が含まれているのか明確ではありません。 –

0
var memuItems = dates.Select(o => o.Date.AddDays(-o.Date.Day + 1)) 
      .GroupBy(o => o, (o, p) => new {MonthAndYear = o.Date, EntriesCount = p.Count()}) 
      .Select(o => new ArchiveMenuItem(streamUrl, o.MonthAndYear.Month, o.MonthAndYear.Year, o.EntriesCount)); 

私は日数を引いて(最初の月)、年と月を使ってグループ分けすることができます。

1
var menuItems = from date in dates 
       group date by new { date.Year, date.Month } into g 
       select new { g.Key.Year, g.Key.Month, Count = g.Count() } into month 
       orderby month.Year, month.Month 
       select new ArchiveMenuItem(streamUrl, month.Month, month.Year, month.Count); 

  1. 年と月
  2. によってグループ日付がグループごとに日付の年、月、番号を選択し、このLINQクエリ
  3. 受注年度別のグループと月
  4. は、グループごとにArchiveMenuItemを作成します。
+0

追加の説明をありがとう。あなたとHandrcraftsmanが基本的に同じことをしているように見えます。 – quakkels

+0

@quakkels、ええ、それは基本的に同じです。 – svick

0

@svickと@danyolgiax、

は、ここで私はダニーのリンクから思い付いたものです:

public class ArchiveMenuModel 
{ 
    private List<ArchiveMenuItem> menuItems; 
    public List<ArchiveMenuItem> MenuItems { get { return menuItems; } } 

    public ArchiveMenuModel(List<DateTime> dates, string streamUrl) 
    { 
     menuItems = new List<ArchiveMenuItem>(); 
     dates = dates.OrderByDescending(x => x).ToList(); 

     var grouped = from d in dates 
         group d by new { month = d.Month, year= d.Year } into d  
         select new { dt = d, count = d.Count() }; 
     foreach(var item in grouped) 
     { 
      menuItems.Add(new ArchiveMenuItem(streamUrl, item.dt.Key.month, item.dt.Key.year, item.count)); 
     } 
    } 
} 
関連する問題