在C#中将嵌套的foreach转换为Linq

时间:2019-03-18 13:08:48

标签: c# linq

如何将该代码段转换为一个Linq? (我想删除foreach)

var resultList = new List<Item>();

var query = dataList.GroupBy(x => new { x.Pruefdatum, x.Plakettenjahr });
foreach (var q in query)
{
   Item temp = new Item();
   foreach (Item item in q)
   {
      switch (item.Plakart)
      {
         case "HU":
            temp.HU = item.Anzahl;
            break;
         case "SP":
            temp.SP = item.Anzahl;
            break;
      }
   }
   temp.Pruefdatum = q.Last().Pruefdatum;
   temp.Plakettenjahr = q.Last().Plakettenjahr;
   resultList.Add(temp);
}

var result = resultList;

数据:

public static List<Item> dataList = new List<Item>()
{
    new Item{Pruefdatum = DateTime.Parse("2019-02-13 00:00:00"), Plakettenjahr = "21", Plakart = "HU", HU = 0, SP = 0, Anzahl =6 }, //0
    new Item{Pruefdatum = DateTime.Parse("2019-02-13 00:00:00"), Plakettenjahr = "21", Plakart = "SP", HU = 0, SP = 0, Anzahl =1 }, //1
    new Item{Pruefdatum = DateTime.Parse("2019-02-15 00:00:00"), Plakettenjahr = "21", Plakart = "HU", HU = 0, SP = 0, Anzahl =1 }, //2
    new Item{Pruefdatum = DateTime.Parse("2019-02-15 00:00:00"), Plakettenjahr = "21", Plakart = "SP", HU = 0, SP = 0, Anzahl =2 }, //3
    new Item{Pruefdatum = DateTime.Parse("2019-02-18 00:00:00"), Plakettenjahr = "21", Plakart = "HU", HU = 0, SP = 0, Anzahl =3 }, //4
    new Item{Pruefdatum = DateTime.Parse("2019-02-18 00:00:00"), Plakettenjahr = "21", Plakart = "SP", HU = 0, SP = 0, Anzahl =1 }, //5
    new Item{Pruefdatum = DateTime.Parse("2019-02-20 00:00:00"), Plakettenjahr = "21", Plakart = "HU", HU = 0, SP = 0, Anzahl =6 }, //6
    new Item{Pruefdatum = DateTime.Parse("2019-02-21 00:00:00"), Plakettenjahr = "21", Plakart = "HU", HU = 0, SP = 0, Anzahl =2 }, //7
    new Item{Pruefdatum = DateTime.Parse("2019-02-22 00:00:00"), Plakettenjahr = "21", Plakart = "HU", HU = 0, SP = 0, Anzahl =8 }, //8
    new Item{Pruefdatum = DateTime.Parse("2019-02-25 00:00:00"), Plakettenjahr = "20", Plakart = "HU", HU = 0, SP = 0, Anzahl =2 }, //9
    new Item{Pruefdatum = DateTime.Parse("2019-02-25 00:00:00"), Plakettenjahr = "20", Plakart = "SP", HU = 0, SP = 0, Anzahl =7 }, //10
    new Item{Pruefdatum = DateTime.Parse("2019-02-25 00:00:00"), Plakettenjahr = "21", Plakart = "HU", HU = 0, SP = 0, Anzahl =9 }, //11
    new Item{Pruefdatum = DateTime.Parse("2019-02-28 00:00:00"), Plakettenjahr = "20", Plakart = "SP", HU = 0, SP = 0, Anzahl =1 }, //12
    new Item{Pruefdatum = DateTime.Parse("2019-02-28 00:00:00"), Plakettenjahr = "21", Plakart = "HU", HU = 0, SP = 0, Anzahl =5 }, //13
};

结果:

public static List<Item> result = new List<Item>()
{
    new Item{Pruefdatum = DateTime.Parse("2019-02-13 00:00:00"), Plakettenjahr = "21", Plakart = "HU", HU = 6, SP = 1}, //0
    new Item{Pruefdatum = DateTime.Parse("2019-02-15 00:00:00"), Plakettenjahr = "21", Plakart = "HU", HU = 1, SP = 2}, //1
    new Item{Pruefdatum = DateTime.Parse("2019-02-18 00:00:00"), Plakettenjahr = "21", Plakart = "HU", HU = 3, SP = 1}, //2
    new Item{Pruefdatum = DateTime.Parse("2019-02-20 00:00:00"), Plakettenjahr = "21", Plakart = "HU", HU = 6, SP = 0}, //3
    new Item{Pruefdatum = DateTime.Parse("2019-02-21 00:00:00"), Plakettenjahr = "21", Plakart = "HU", HU = 2, SP = 0}, //4
    new Item{Pruefdatum = DateTime.Parse("2019-02-22 00:00:00"), Plakettenjahr = "21", Plakart = "HU", HU = 8, SP = 0}, //5
    new Item{Pruefdatum = DateTime.Parse("2019-02-25 00:00:00"), Plakettenjahr = "20", Plakart = "HU", HU = 2, SP = 7}, //6
    new Item{Pruefdatum = DateTime.Parse("2019-02-25 00:00:00"), Plakettenjahr = "21", Plakart = "HU", HU = 9, SP = 0}, //7
    new Item{Pruefdatum = DateTime.Parse("2019-02-28 00:00:00"), Plakettenjahr = "20", Plakart = "SP", HU = 0, SP = 1}, //8
    new Item{Pruefdatum = DateTime.Parse("2019-02-28 00:00:00"), Plakettenjahr = "21", Plakart = "HU", HU = 5, SP = 0} //9
};

1 个答案:

答案 0 :(得分:1)

类似这样的东西

    dataList
        .GroupBy(x => new { x.Pruefdatum, x.Plakettenjahr })
        .Select(x => new Item()
        {
            Pruefdatum = x.Key.Pruefdatum,
            Plakettenjahr = x.Key.Plakettenjahr,
            HU = x.FirstOrDefault(y => y.Plakart == "HU")?.Anzahl ?? 0,
            SP = x.FirstOrDefault(y => y.Plakart == "SP")?.Anzahl ?? 0,
        });

编辑:我错过了Plakart字段,但是从原始示例(temp从未分配Plakart来确定其值)上也不清楚。按照这种观点,我上面的清单所产生的结果与原始代码清单所产生的结果完全相同,尽管这与声称是结果的清单不匹配。

此外,我使用的是Key而不是Last(),因为如果已经按查询结果分组,则无需使用查询结果中的最后一项。这意味着在第一个或最后一个或任何一个之间将不会有任何变化。如果排序顺序 很重要,则可以随时将Key换回Last()

现在,基于结果数据集,我可以从中推导出的唯一确定Plakart值的规则是:HU> 0然后HU else SP,这将导致将其添加到我的选择中条款:

            Plakart = x.Any(y => y.Plakart == "HU" && y.Anzahl > 0) ? "HU" : "SP",