简体   繁体   English

使用Linq进行C#集合操作

[英]c# collection manipulation with Linq

I have a collection in this format 我有这种格式的收藏

IList<ReportRow> MyCollection

Where ReportRow is a 如果ReportRow是

Dictionary<string, object>

So MyCollection might look like this: 所以MyCollection可能看起来像这样:

    Id1 Id2 Value   Status  Entered
    123 2   56      New     50:01.7
    123 2   76      Old     50:23.0
    123 2   12      New     50:23.0
    127 3   54      Old     50:23.0
    127 3   77      New     59:23.0

... ...

Is there a way in Linq that I can do this: What I need to do is for each Id1+Id2 combination I need to output the Value where Status is New and where the status is Old. Linq中有什么方法可以做到:我需要为每个Id1 + Id2组合输出状态为“新”和状态为“老”的值。 There might be multiple New values for an Id1+Id2 combination so it should pick up the latest New record, using the Entered column to sort. Id1 + Id2组合可能有多个新值,因此它应该使用Entered列进行排序以获取最新的New记录。

The new record will contain all the records plus 1 extra column like so: 新记录将包含所有记录以及1个额外的列,如下所示:

    Id1 Id2 NewValue    OldValue    Entered
    123 2   12          76          50:23.0
    127 3   77          54          59:23.0

Any help with this would be great 任何帮助都会很棒

from row in MyCollection
group row by new { row.Id1, row.Id2 } into g
let lastNew = g.OrderByDescending(r => r.Entered)
               .FirstOrDefault(r => r.Status == "New")
let lastOld = g.OrderByDescending(r => r.Entered)
               .FirstOrDefault(r => r.Status == "Old")
select new {
   Id1 = g.Key.Id1,
   Id2 = g.Key.Id2,
   NewValue = (lastNew == null) ? null : (int?)lastNew.Value,
   OldValue = (lastOld == null) ? null : (int?)lastOld.Value,
   Entered = g.OrderByDescending(r => r.Entered).First().Entered
}

This should do it (or be close as this is off the top of my head) 这应该做到(或者离我的头很近)

collection.OrderByDescending(r => r.Value.Entered)
          .GroupBy(r => {r.Id1, r.Id2)
          .Select(g => new {
               Id1 = g.Key.Id1,
               Id2 = g.Key.Id2,
               NewValue = g.FirstOrDefault(v => v.Status == "New").Value ?? 0,
               OldValue = g.FirstOrDefault(v => v.Status == "Old").Value ?? 0,
               Entered = g.Last().Entered
           })

If you don't care for the dictionary string key you could do 如果您不在乎字典字符串键,则可以这样做

collection.SelectMany(d => d.Value)
          .OrderByDescending(r => r.Value.Entered)
          .GroupBy(rr => {rr.Value.Id1, rr.Value.Id2)
          .Select(g => new {
               Id1 = g.Key.Id1,
               Id2 = g.Key.Id2,
               NewValue = g.FirstOrDefault(v => v.Status == "New").Value ?? 0,
               OldValue = g.FirstOrDefault(v => v.Status == "Old").Value ?? 0,
               Entered = g.Last().Entered
           })

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM