Pregunta

Quiero aprovechar los resultados de una cláusula where en una lista y luego tomar ese conjunto de resultados y crear sólo un nuevo tipo que tiene todos sus campos construidos a partir de agregados de la consulta original. Así que dado el ejemplo básico de abajo, hay alguna forma de combinar las declaraciones 2 LINQ en una sola? Si el original donde tiene ninguna fila, entonces debería devolver null. Gracias!

    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
        }

Actualización: Para mi situación, el conjunto original tiene un montón de artículos, pero después de la cláusula en el que el conjunto de resultados es muy pequeño. Enumerando sobre el segundo set en varias ocasiones no debería ser un problema. También tengo que usar primero y el último en el set para obtener un valor de esos registros. El grupo de respuesta que funciona mejor para mí. La forma agregada es muy interesante y creo que tienen otro uso para eso.

¿Fue útil?

Solución

( 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()

Otros consejos

Esta solución itera la lista sólo una vez con Aggregate(), pero para las listas vacías se devolverá el valor de la semilla. Por cierto, los valores de semillas son int.MaxValue y int.MinValue porque Math.Min(int.MaxValue, C) siempre devolverá C y del mismo modo Math.Max(int.MinValue, C) siempre devolverá 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)
                  });
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top