如何将嵌套的 foreach 循环转换为 C# 中的单个 LINQ 查询?

问题描述 投票:0回答:1

如何将此代码片段转换为一个

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
};
c# linq
1个回答
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
值的规则是 if HU > 0 then HU else SP,这将导致将其添加到我的 select 子句中:

            Plakart = x.Any(y => y.Plakart == "HU" && y.Anzahl > 0) ? "HU" : "SP",
© www.soinside.com 2019 - 2024. All rights reserved.