Есть ли лучшее решение для сортировки по списку <DateTime>? - PullRequest
0 голосов
/ 02 июля 2011

Я пишу класс для меню ASP.NET MVC.Я хочу иметь возможность взять список всех записей блога и создать меню архива, похожее на это:

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))

Если бы я мог избежать такого уродливого оператора if, это было бы здорово!

Ответы [ 5 ]

2 голосов
/ 02 июля 2011
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();
1 голос
/ 02 июля 2011
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);

Этот запрос LINQ

  1. группирует даты по году и месяцу
  2. выбирает год, месяц и количество дат для каждой группы
  3. заказовгруппы по году и месяцу
  4. создают ArchiveMenuItem для каждой группы
0 голосов
/ 02 июля 2011

@ 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));
        }
    }
}
0 голосов
/ 02 июля 2011
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));

Я вычитаю дни, чтобы иметь дату (до первого числа месяца), поэтому я могу группировать, используя год и месяц.

0 голосов
/ 02 июля 2011

Что-то в этом духе должно работать:

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

Я не знаю имени свойства, которое содержит DateTime, но его нужно настроить как,

  menuItems.GroupBy(x => x.(datetime).Month + "/" + x.(datetime).Year); 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...