Linq - 如何聚合另一个查询的结果

发布于 2024-07-17 09:00:44 字数 776 浏览 4 评论 0原文

我想获取列表上 where 子句的结果,然后获取该结果集并创建一种新类型,该类型的所有字段均由原始查询的聚合构造而成。 因此,给出下面的基本示例,是否有办法将 2 个 linq 语句合并为一个? 如果原始 where 没有行,那么它应该返回 null。 谢谢!

    class Foo
    {
        public int A { get; set; }
        public int B { get; set; }
    }
    List<Foo> lst = GetFooList();

        var q = (from f in lst
                 where f.A > 3
                 select f).ToList();
        if (q.Count != 0)
        {
            var qq = new
            {
                MinA = q.Min(l => l.A),
                MaxB = q.Max(h => h.B),
            };
            // now do something with qq
        }

更新: 对于我的情况,原始集有很多项目,但在 where 子句之后,结果集非常小。 多次枚举第二组应该不成问题。 另外,我需要使用集合中的第一个和最后一个来从这些记录中获取值。 按答案分组最适合我。 聚合方式非常有趣,我认为它还有其他用途。

I want to take the results of a where clause on a list and then take that result set and create just one new type that has all its fields constructed from aggregates of the original query. So given the basic example below, is there anyway to combine the 2 linq statements into one? If the original where has no rows then it should return null. Thanks!

    class Foo
    {
        public int A { get; set; }
        public int B { get; set; }
    }
    List<Foo> lst = GetFooList();

        var q = (from f in lst
                 where f.A > 3
                 select f).ToList();
        if (q.Count != 0)
        {
            var qq = new
            {
                MinA = q.Min(l => l.A),
                MaxB = q.Max(h => h.B),
            };
            // now do something with qq
        }

Update:
For my situation, the original set has lots of items but after the where clause the result set is very small. Enumerating over the second set several times should not be a problem. Also I need to use first and last on the set to get a value from those records. The group by answer will work best for me. The aggregate way is very interesting and I think have another use for that.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

仄言 2024-07-24 09:00:44

此解决方案仅使用 Aggregate() 迭代列表一次,但对于空列表,它将返回种子值。 顺便说一句,种子值为 int.MaxValueint.MinValue 因为 Math.Min(int.MaxValue, C) 将始终返回C 以及同样的 Math.Max(int.MinValue, C) 将始终返回 C。

var b = lst.Where(f => f.A > 3)
           .Aggregate(
                  // seed, initial values
                  new
                  {
                     MinA = int.MaxValue,
                     MaxB = int.MinValue
                  },

                  // accumulator function
                  (a,f) => new
                  {
                     MinA = Math.Min(a.MinA , f.A),
                     MaxB = Math.Max(a.MaxB , f.B)
                  });

This solution iterates the list only once with Aggregate(), but for empty lists it will return the seed value. By the way, the seed values are int.MaxValue and int.MinValue because Math.Min(int.MaxValue, C) will always return C and likewise Math.Max(int.MinValue, C) will always return C.

var b = lst.Where(f => f.A > 3)
           .Aggregate(
                  // seed, initial values
                  new
                  {
                     MinA = int.MaxValue,
                     MaxB = int.MinValue
                  },

                  // accumulator function
                  (a,f) => new
                  {
                     MinA = Math.Min(a.MinA , f.A),
                     MaxB = Math.Max(a.MaxB , f.B)
                  });
默嘫て 2024-07-24 09:00:44
( from f in GetFooList()
  where f.A > 3
  group f by 1 into g
  let MinA=g.Min(l=>l.A)
  let MaxB=g.Max(h=>h.B)
  select new {MinA, MaxB} ).SingleOrDefault()
( from f in GetFooList()
  where f.A > 3
  group f by 1 into g
  let MinA=g.Min(l=>l.A)
  let MaxB=g.Max(h=>h.B)
  select new {MinA, MaxB} ).SingleOrDefault()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文