LINQ-Query按日期范围将对象的List(按DateTime asc排序)拆分为子列表

时间:2016-04-26 10:02:33

标签: c# linq list date

所以,我的Basket包含BasketItems。每个项目都有一个MenuDate。现在我想从这些项目中创建Orders,条件是:每个Order应该有一周的项目(从星期一开始)。

现在我知道了,我可以创建多个foreach-constructs,甚至可能一段时间(true),我检查所有日期和每次星期一被击中,但这一切对我来说似乎有些笨拙。最好的方法是,以某种方式使用LINQ-Query,就像编写的Code I&Ve;但是这并没有给出预期的值:

var basketItems = currBasket.Items.OrderBy(y => y.MenuDate).ToList();
            if (basketItems.Count() > 0)
            {
                List<List<BasketDay>> listOfItemsPerWeek = basketItems
                .GroupBy(p => p.MenuDate >= basketItems.First().MenuDate.StartOfWeek(DayOfWeek.Monday) 
                            && p.MenuDate < basketItems.First().MenuDate.StartOfWeek(DayOfWeek.Monday).AddDays(7))
                .Select(g => g.ToList())
                .ToList();
            }

其中startofweek是一个扩展方法,我使用给我一个给定日期时间的前一个星期一(或星期一,如果它的星期一,当然)。

给了我一些List<BasketDay>包含currBasket.Items的所有菜单,其中MenuDates位于星期一和星期日之间(23:59:59)。

到目前为止,我已经尝试了所有内容,现在我没有想法,希望你能帮助我。

Beste问候

修改

为了说清楚,假设我们在这里的食品分支中:BasketDay包含一天的菜单。

这是一个示例用例(删除年份,因为它不重要): 客户在1月的以下日期将菜单添加到购物篮中:

星期一01.01。, 星期三03.01。 周五05.01 周日07.01。 星期一08.01。 星期二09.01。

所以他的篮子包含6个项目。

现在我需要的是:将BasketDay个实例列表分成每周List<BasketDay>

上面的LINQ-Query应该为我做这个。之后,我可以像这样创建单独的订单对象:

foreach(weekOrder in listOfItemsPerWeek){...}

其中listOfItemsPerWeek包含2 List<BasketDay>,其中一个包含4个项目(01.01。 - 07..01。),第二个包含2个项目(08.01。和09.01。)

希望这更清楚。

2 个答案:

答案 0 :(得分:2)

我建议声明一个可用于group by的临时变量,例如日历周可能是一个不错的选择。

var calendar = CultureInfo.CurrentCulture.Calendar;

var items = (from item in basketItems
             let calendarWeek = calendar.GetWeekOfYear(item.MenuDate, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday)
             group item by calendarWeek into baskets
             select baskets);

编辑: CalendarWeekRule选择确定一年中第一周的方式。这与文化不同,我选择了德国使用的ISO definition。由于您只对从星期一到星期日的分组感兴趣,绝对价值可能与您无关,因此您可以选择您喜欢的任何规则。如果您更喜欢Lambda,代码如下所示:

var calendar = CultureInfo.CurrentCulture.Calendar;

var items = basketItems.GroupBy(i => calendar.GetWeekOfYear(i.MenuDate, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday));

答案 1 :(得分:0)

您需要计算每个项目的一年中的一周(周数),然后您可以简单地对一年中的一周进行分组。以下是我将如何做到这一点,我也假设我们有多年的日期范围,所以分组将是年份和周数,我已将周的开始设置为星期一,如果你愿意,你可以改变它

public class Item
{
    public string Name { get; set; }
    public DateTime ItemDate { get; set; }
}
public class ItemWithWeekInfo
{
    public int Year { get; set; }

    public int WeekOfTheYear { get; set; }

    public Item Item { get; set; }
}

public class Order
{
    public int Year { get; set; }
    public int WeekOfTheYear { get; set; }
    public List<Item> Items { get; set; }
}

DateTimeFormatInfo dfi = DateTimeFormatInfo.CurrentInfo;
Calendar cal = dfi.Calendar;
var groups =  items.Select(p => new ItemWithWeekInfo
        {
            Year = p.ItemDate.Year,
            WeekOfTheYear = cal.GetWeekOfYear(p.ItemDate, dfi.CalendarWeekRule, DayOfWeek.Monday),
            Item = p
        }).GroupBy(p => new { p.Year , p.WeekOfTheYear}).Select(p=>new Order
        {
            Year = p.Key.Year,
            WeekOfTheYear = p.Key.WeekOfTheYear,
            Items = p.Select(x=> x.Item).ToList()
        }).ToList();

如果您已经有列表,这将有效,但如果您正在进行数据库调用,则无法执行此操作,那么您将需要使用一些数据库支持的函数来计算年份和周数。