C# LINQ查询将对象列表(按DateTime asc排序)按daterange拆分为子列表
因此,我这里有一个C# LINQ查询将对象列表(按DateTime asc排序)按daterange拆分为子列表,c#,linq,list,date,C#,Linq,List,Date,因此,我这里有一个篮子,包含篮子项目。每个项目都有一个菜单日期。现在我想从这些项目中创建订单,条件是:每个订单都应该包含一周的项目(从这里的星期一开始) 现在我知道了,我可以创建多个foreach构造,甚至可以在一段时间内(真的)检查所有的日期,并且每次星期一被点击,但这一切对我来说似乎有点不太正常。最理想的情况是,使用类似于我编写的代码的LINQ查询,但这不会返回预期值: var basketItems = currBasket.Items.OrderBy(y => y.MenuDate
篮子
,包含篮子项目
。每个项目都有一个菜单日期
。现在我想从这些项目中创建订单
,条件是:每个订单
都应该包含一周的项目(从这里的星期一开始)
现在我知道了,我可以创建多个foreach构造,甚至可以在一段时间内(真的)检查所有的日期,并且每次星期一被点击,但这一切对我来说似乎有点不太正常。最理想的情况是,使用类似于我编写的代码的LINQ查询,但这不会返回预期值:
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();
}
其中listOfItemsPerWeek
包含2个List
,一个包含4个项目(01.01.-07..01),第二个包含2个项目(08.01.和09.01.)
希望这能让事情变得更清楚 我建议声明一个临时变量,可用于按分组,例如日历周可能是一个不错的选择
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);
编辑:日历周规则
选择如何确定一年中的第一周。这在不同的文化中是不同的,我选择了在德国这里使用的。因为您只对从周一到周日的分组感兴趣,所以绝对值可能与您无关,因此您可以选择您喜欢的任何规则。如果您更喜欢Lambda,代码如下所示:
foreach(weekOrder in listOfItemsPerWeek){...}
var calendar = CultureInfo.CurrentCulture.Calendar;
var items = basketItems.GroupBy(i => calendar.GetWeekOfYear(i.MenuDate, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday));
您需要为每个项目计算一年中的一周(周数),然后您可以简单地按一年中的一周分组。下面是我将如何做,我还假设我们有多年的日期范围,因此分组将根据年和周数,我已将一周的开始设置为周一,如果您愿意,可以更改它
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();
公共类项目
{
公共字符串名称{get;set;}
公共日期时间项日期{get;set;}
}
公共类项Withweekinfo
{
公共整数年{get;set;}
年度公共整数周{get;set;}
公共项项{get;set;}
}
公共阶级秩序
{
公共整数年{get;set;}
年度公共整数周{get;set;}
公共列表项{get;set;}
}
DateTimeFormatInfo dfi=DateTimeFormatInfo.CurrentInfo;
日历校准=dfi.日历;
变量组=项。选择(p=>newitemWithweekinfo
{
年份=p.ItemDate.Year,
WeekOfTheYear=cal.GetWeekOfYear(p.ItemDate,dfi.CalendarWeekRule,DayOfWeek.Monday),
项目=p
}).GroupBy(p=>new{p.Year,p.WeekOfTheYear})。选择(p=>neworder
{
年份=p.Key.Year,
WeekOfTheYear=p.Key.WeekOfTheYear,
Items=p.Select(x=>x.Item).ToList()
}).ToList();
如果您已经有了列表,这将起作用,但是如果您正在进行数据库调用,您将无法执行此操作,那么您需要使用一些数据库支持的函数来计算年份和周数。是否
BasketDay
您所说的订单
?你想要什么还不太清楚。该组所需的密钥是什么?有时LINQ无助于提高代码的可读性。非常感谢您提供此解决方案。不过,有两个问题:1)这是否可能像我在问题中所做的那样,作为一个lambda?我已使用let
搜索,但未找到任何内容。2) 请您解释一下CalendarWeekRule.FirstFourDayWeek
在这种情况下做了什么?这对我来说有点不清楚。