C# groupby之后使用linq保留顺序,然后选择many

C# groupby之后使用linq保留顺序,然后选择many,c#,linq,C#,Linq,有没有办法在这个linq表达式之后保持顺序 var results = DateList .GroupBy(x => x.Date.Subtract(firstDay).Days / 7 + 1) .SelectMany(gx => gx, (gx, x) => new {Week = gx.Key,DateTime =x,Count = gx.Count(),}); 我发现了这一点,但我不确定是否是GroupBy或SelectMany在问题中起到了作

有没有办法在这个linq表达式之后保持顺序

var results =
  DateList
    .GroupBy(x => x.Date.Subtract(firstDay).Days / 7 + 1)
     .SelectMany(gx => gx, (gx, x) => new {Week =  gx.Key,DateTime =x,Count = gx.Count(),});

我发现了这一点,但我不确定是否是GroupBy或SelectMany在问题中起到了作用

是的,如果您首先选择日期列表并将其与索引相结合,使用一个代理,该代理使用第二个(
int
)参数,该参数与序列中项目的索引一起调用:

DateList
    .Select((dateTime, idx) => new {dateTime, idx})
    .GroupBy(x => x.dateTime.Date.Subtract(firstDay).Days / 7 + 1)
…并通过linq链保持价值

    .SelectMany(gx => gx, (gx, x) => new {Week =  gx.Key,
                                          DateTime = x.dateTime, 
                                          Count = gx.Count(), 
                                          x.idx})
…然后使用它重新排序输出

    .OrderBy(x => x.idx)
…并将其从最终选择中删除

    .Select(x => new {x.Week, x.DateTime, x.Count});

然后,您可以保持与原始列表相同的顺序。

是的,如果您首先选择日期列表并将其与索引相结合,使用一个委托,该委托使用第二个(
int
)参数,该参数与序列中项目的索引一起调用:

DateList
    .Select((dateTime, idx) => new {dateTime, idx})
    .GroupBy(x => x.dateTime.Date.Subtract(firstDay).Days / 7 + 1)
…并通过linq链保持价值

    .SelectMany(gx => gx, (gx, x) => new {Week =  gx.Key,
                                          DateTime = x.dateTime, 
                                          Count = gx.Count(), 
                                          x.idx})
…然后使用它重新排序输出

    .OrderBy(x => x.idx)
…并将其从最终选择中删除

    .Select(x => new {x.Week, x.DateTime, x.Count});

然后,您可以保持与原始列表相同的顺序。

@spender的解决方案很好,但是如果没有
OrderBy
,它可以做到吗?它可以,因为我们可以使用索引直接索引到数组中,但它不是一个linq查询:

var resultsTmp =
    DateList.Select((d, i) => new { d, i })
    .GroupBy(x => x.d.Date.Subtract(firstDay).Days / 7 + 1)
    .SelectMany(gx => gx, (gx, x) => new { Week = gx.Key, DateTime = x.d, Count = gx.Count(), x.i })
    .ToArray();

var resultsTmp2 = resultsTmp.ToArray();
foreach (var r in resultsTmp) { resultsTmp2[r.i] = r; };
var results = resultsTmp2.Select(r => new { r.Week, r.DateTime, r.Count });
看起来有点复杂。我可能会做一些更直接的事情,比如:

var DateList2 = DateList.Select(d => new { DateTime = d, Week = d.Subtract(firstDay).Days / 7 + 1 }).ToArray();
var weeks = DateList2.GroupBy(d => d.Week).ToDictionary(k => k.Key, v => v.Count());
var results = DateList2.Select(d2 => new { d2.Week, d2.DateTime, Count = weeks[d2.Week] });

@spender的解决方案很好,但是如果没有OrderBy,它能做到吗?它可以,因为我们可以使用索引直接索引到数组中,但它不是一个linq查询:

var resultsTmp =
    DateList.Select((d, i) => new { d, i })
    .GroupBy(x => x.d.Date.Subtract(firstDay).Days / 7 + 1)
    .SelectMany(gx => gx, (gx, x) => new { Week = gx.Key, DateTime = x.d, Count = gx.Count(), x.i })
    .ToArray();

var resultsTmp2 = resultsTmp.ToArray();
foreach (var r in resultsTmp) { resultsTmp2[r.i] = r; };
var results = resultsTmp2.Select(r => new { r.Week, r.DateTime, r.Count });
看起来有点复杂。我可能会做一些更直接的事情,比如:

var DateList2 = DateList.Select(d => new { DateTime = d, Week = d.Subtract(firstDay).Days / 7 + 1 }).ToArray();
var weeks = DateList2.GroupBy(d => d.Week).ToDictionary(k => k.Key, v => v.Count());
var results = DateList2.Select(d2 => new { d2.Week, d2.DateTime, Count = weeks[d2.Week] });

GroupBy
保留顺序(),而
SelectMany
只在集合()上迭代,所以我不明白它为什么会改变。你确定没有保留任何顺序吗?@Jeroenvanevel想一想你在说什么:将以下序列分成奇数和偶数:[1,1,2,2,3,3,4,4,5,5,6,6]所以现在你有了[1,1,3,3,5,5],[2,2,4,4,6,6](是的,每个组中都保留了顺序)。。。现在在这些组中选择Many,您将得到[1,1,3,3,5,5,2,2,4,4,6,6](再次保留顺序)。。。但是在组合2时,显然没有保留顺序。感谢@spender
GroupBy
保留顺序()和
SelectMany
只在集合()上迭代,所以我不明白为什么它会改变。你确定没有保留任何顺序吗?@Jeroenvanevel想一想你在说什么:将以下序列分成奇数和偶数:[1,1,2,2,3,3,4,4,5,5,6,6]所以现在你有了[1,1,3,3,5,5],[2,2,4,4,6,6](是的,每个组中都保留了顺序)。。。现在在这些组中选择Many,您将得到[1,1,3,3,5,5,2,2,4,4,6,6](再次保留顺序)。。。但在结合这两个元素时,显然没有保留顺序。感谢您的解释@spenderI得到了一个空白结果。我所做的是运行这个:var row2=results.ElementAt(ii);第[“周”]=第2行。周;行[“计数”]=行2.Count;行[“DateTime2”]=行2.DateTime;将每个值添加到datagridview中。@Sewder我无法帮助您解决评论中描述得如此模糊的问题。@loneshark99评论不是提出新问题的好地方。如果你想让我看一看的话,请随意点击这里。我得到了一个空白结果。我所做的是运行这个:var row2=results.ElementAt(ii);第[“周”]=第2行。周;行[“计数”]=行2.Count;行[“DateTime2”]=行2.DateTime;将每个值添加到datagridview中。@Sewder我无法帮助您解决评论中描述得如此模糊的问题。@loneshark99评论不是提出新问题的好地方。如果你想让我看一看的话,请随意在这里打电话给我。