LINQ 中按特定时间范围分组

发布于 2024-11-26 08:51:34 字数 710 浏览 4 评论 0原文

我有一个

List<Advertisement> 

其中 Advertisement 包含

public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }

我想要做的是使用 GroupBy 按三个特定时间范围对 List 中的元素进行分组。三个时间范围如下:

  • x => x.开始日期> DateTime.Now.Subtract(TimeSpan.FromDays(1))
  • x =>; x.开始日期> DateTime.Now.Subtract(TimeSpan.FromDays(7))
  • x =>; x.开始日期> DateTime.Now.Subtract(TimeSpan.FromDays(365))

因此,开始日期为最后一天的元素、开始日期为上周的元素以及开始日期为去年的元素。

去年的元素组应包括开始日期在上周和最后一天的元素。上周的元素组应该包括最后一天的元素。

我似乎想不出该怎么做。干杯。

I have a

List<Advertisement> 

where Advertisement contains

public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }

What I want to do is group the elements in the List<Advertisement> by three specific time ranges using a GroupBy. The three time ranges are as follows:

  • x => x.StartDate > DateTime.Now.Subtract(TimeSpan.FromDays(1))
  • x => x.StartDate > DateTime.Now.Subtract(TimeSpan.FromDays(7))
  • x => x.StartDate > DateTime.Now.Subtract(TimeSpan.FromDays(365))

So elements with start date in the last day, elements with start date in the last week and elements with start date in the last year.

The group of elements from the last year should include those elements with a start date in the last week and day. And the group of elements from the last week should include those elements from the last day.

I just cant seem to think how to do this. Cheers.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

粉红×色少女 2024-12-03 08:51:34

由于您希望每个组也包含之前的组内容(例如上周包括最后一天),我构建了一个联合查询。

var today=items.Where(l=>l.StartDate>DateTime.Now.Subtract(TimeSpan.FromDays(1)));
var lastweek=items.Where(l=>l.StartDate>DateTime.Now.Subtract(TimeSpan.FromDays(7)));
var lastyear=items.Where(l=>l.StartDate>DateTime.Now.Subtract(TimeSpan.FromDays(365)));


var result = today.Select(d => new { Group="Last Day",item=d})
                  .Union(lastweek.Select(w => new {Group="Last Week",item=w}))
                  .Union(lastyear.Select(y => new {Group="Last Year",item=y}))
                  .GroupBy (l => l.Group,l=>l.item);

该查询的工作原理是它创建 3 个子查询来选择相关数据。
然后,每个查询都使用选择运算符来选择匹配组名称和投影到匿名对象中的原始项目。 (基本上创建一个新对象,其中组名作为一个属性,原始项目作为另一个属性)。
然后,我使用 union 将多个结果合并到一个大列表中。 (Union 具有删除重复项的附加属性,但不应该有任何重复项)。一旦我有了大列表,我就可以按组名进行分组,第二个参数基本上将原始项目放回到组值中。

As you want each group to also include the previous groups contents (eg lastweek includes last day) I've constructed a union query

var today=items.Where(l=>l.StartDate>DateTime.Now.Subtract(TimeSpan.FromDays(1)));
var lastweek=items.Where(l=>l.StartDate>DateTime.Now.Subtract(TimeSpan.FromDays(7)));
var lastyear=items.Where(l=>l.StartDate>DateTime.Now.Subtract(TimeSpan.FromDays(365)));


var result = today.Select(d => new { Group="Last Day",item=d})
                  .Union(lastweek.Select(w => new {Group="Last Week",item=w}))
                  .Union(lastyear.Select(y => new {Group="Last Year",item=y}))
                  .GroupBy (l => l.Group,l=>l.item);

How this query works is it creates 3 sub queries to select the relevant data.
Each query then uses a select operator to select the match group name and the original item projected into an anonymous object. (Basically creates a new object with the groupname as one property and the original Item as another).
I then use union to combine the multiple results together in one big list. (Union has the added property that it strips duplicates, but there shouldn't be any). Once I have the big list I can then Group by the groupname, the second parameter basically puts the orginal item back in as the group value.

征棹 2024-12-03 08:51:34

您可以创建一个方法(或扩展),它将返回特定于组的一些值,然后按它进行分组。

You can create a method (or extension) wich will return some value specific to a group, and then make grouping by it.

机场等船 2024-12-03 08:51:34

一种方法可能是编写一个扩展方法,该方法返回它所属的类别。

public static int GetCategory(this Advertisement advert)
{
    if(x.StartDate > DateTime.Now.Subtract(TimeSpan.FromDays(1)))
    {
        return 1;
    }
etc...
}

然后您可以按 GetCategory 属性进行分组。返回枚举而不是整数可能更好。

One method may be to write an extension method which returns the category that it falls into.

public static int GetCategory(this Advertisement advert)
{
    if(x.StartDate > DateTime.Now.Subtract(TimeSpan.FromDays(1)))
    {
        return 1;
    }
etc...
}

then you can group by the GetCategory property. It is probably better to return an Enum instead of an integer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文