将聚合写为Sql语法

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

我真的很想理解聚合是如何工作的,我有一个解决方案将IEnumerable映射到更新的C#7元组。

如果这是作为Linq Sql语法编写的话,我想我可以理解这一点。

有人想要刺它吗?


IEnumerable<(string Key, string Value)> many = DataToPivot();

(string XXXX, string YYYY, string ZZZZ) agg = 
many.Aggregate((XXXX: default(string),
                YYYY: default(string),
                ZZZZ: default(string)),
                  (a, i) =>
                  {
                      switch (i.Key)
                      {
                          case "xxxx":
                              return (i.Value, a.YYYY, a.ZZZZ);
                          case "yyyy":
                              return (a.XXXX, i.Value, a.ZZZZ);
                          case "zzzz":
                              return (a.XXXX, a.YYYY, i.Value);
                          default:
                              return a;
                      }
                  });
c# linq
1个回答
2
投票

据我所知,Aggregate没有查询语法(有关更多信息,请参阅documentation)。文档还应该能够解释函数的工作原理。

您正在使用的重载是获取聚合的初始值(第一个参数),并将累加函数(第二个参数)应用于每个元素,返回中间聚合值。因此,您的示例从输入数据生成3个字符串,基本上返回每个键的最后一个字符串值(或者当输入数据不包含该键的任何项时default(string))。

如果这是您的要求,您不需要(也不应该)使用聚合函数,因为您没有聚合。您可以使用以下示例获得相同的结果(假设many输入中存在所有键):

IEnumerable<(string Key, string Value)> many = DataToPivot();

var d = many.GroupBy(i => i.Key)
            .ToDictionary(g => g.Key, g => g.Last().Value);

(string XXXX, string YYYY, string ZZZZ) agg = (d["xxxx"], d["yyyy"], d["zzzz"]);

如果不需要元组,则下面的句柄也会处理数据集中根本不存在键的情况(如果密钥不存在,将返回默认值):

d.TryGetValue("xxxx", out string x);
d.TryGetValue("yyyy", out string y);
d.TryGetValue("zzzz", out string z);

将使用Aggregate,例如对于字符串连接 - 但在那里你会选择String.Join()

many.GroupBy(i => i.Key)
    .ToDictionary(g => g.Key, g => string.Join(",", g));

如果您仍想使用Aggrergate,可以像这样重写它:

many.GroupBy(i => i.Key)
    .ToDictionary(g => g.Key, g => g.Aggregate((a, i) => i));

这基本上是使用Last()实现的Aggregate();和TryGetValue你可以得到你需要的东西。

更一般地说:使用这种方法,您可以容纳多个键值,而无需专门编写它们。在这种情况下,你可能甚至不需要ToDictionary电话,例如像这样:

many.GroupBy(i => i.Key)
    .Select(g => new { g.Key, Result = g.Aggregate((a, i) => i) })
    .ToList();
© www.soinside.com 2019 - 2024. All rights reserved.