如何在LINQ中分组并选择(创建增量)?

时间:2019-01-17 09:44:41

标签: c# linq

我有此代码:

foreach (var item in orderedItems.Select((x, i) => new { x, i }) 
{
  item.x.Index = item.i + 1;
  //some stuff here
}

它允许我设置项目的索引。 现在,我需要按某些参数(item.Date)对项目进行分组,并仅在组内为项目创建索引。例如:{group1:1,2,3} {group2:1,2}

当我尝试类似:

foreach (var taskGr in orderedItems.GroupBy(x=>x.TaskDate).Select((x, i) => new { x, i }));
{
  foreach (var task in taskGr)
  {
    //task.Index =...           
  }
}

我知道了

  

“类型   '{x:System.Linq.IGrouping,Models.Task>,   i:int}'不能枚举”

关于taskGr

有什么办法可以通过LINQ查询吗?

2 个答案:

答案 0 :(得分:0)

答案将取决于您的要求。假设您只需要每个组的索引,而无需分组的枚举本身(而且创建项相对便宜),则可以执行以下操作

var itemsWithIndexPerGroup = orderedItems.GroupBy(item => item.Group)
                                         .Select(group => group.Select((item, index) => new Item(item) { Index = index }))
                                         .SelectMany(item => item);

说明:您首先将IEnumerableItem.Group分组,这实际上产生了IEnumerableIEnumerable s。然后,我们选择每个IEnumerable,并将其项目投影到带有索引的新项目。仍然会产生IEnumerable<IEnumerable<Item>>,因此我们将使用SelectMany从嵌套的IEnumerable<Item>返回所有项的平面IEnumerables

如果您需要使用分组密钥分组的IEnumerable,仍然可以在末尾将此GroupBy分组。如果您需要分组IEnumerables, but don't need the group key, you can simply omit the SelectMany`。

答案 1 :(得分:0)

您可以做类似的事情

var orderedItems = Enumerable.Range(1,15)
                   .Select(x=> new Order{Date = DateTime.Now.AddDays(x%3)});
    var indexItems = orderedItems.GroupBy(x=>x.Date)
                   .SelectMany(x=>x.ToList()
                            .Select((c,index)=>new Order{Date= x.Key, Index=index+1}));

订单定义为

public class Order
{
    public int Index{get;set;}
    public DateTime Date{get;set;}
}

这将输出为

Index Date
1 18-01-2019 15:59:47 
2 18-01-2019 15:59:47 
3 18-01-2019 15:59:47 
4 18-01-2019 15:59:47 
1 19-01-2019 15:59:47 
2 19-01-2019 15:59:47 
3 19-01-2019 15:59:47 
1 17-01-2019 15:59:47 
2 17-01-2019 15:59:47 
3 17-01-2019 15:59:47