简体   繁体   English

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

[英]Linq - How to aggregate the results of another query

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. 我想在列表中获取where子句的结果,然后获取该结果集并创建一个新类型,其所有字段都是从原始查询的聚合构造的。 So given the basic example below, is there anyway to combine the 2 linq statements into one? 所以给定下面的基本示例,无论如何将两个linq语句合并为一个? If the original where has no rows then it should return null. 如果原始的地方没有行,那么它应该返回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. 更新:对于我的情况,原始集有很多项,但在where子句之后,结果集非常小。 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. 此外,我需要在集合上使用first和last来从这些记录中获取值。 The group by answer will work best for me. 答案小组最适合我。 The aggregate way is very interesting and I think have another use for that. 聚合方式非常有趣,我认为还有其他用途。

This solution iterates the list only once with Aggregate() , but for empty lists it will return the seed value. 此解决方案仅使用Aggregate()迭代列表一次,但对于空列表,它将返回种子值。 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. 顺便说一下,种子值是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)
                  });
( 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()

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

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