views:

101

answers:

2

I have a LINQ query which gives me a list with a number of child lists all with double values.

I want to get a queryResult from this.

How can I get the first, the last, the highest and the lowest double value?

Should it be a new object and should the new return values be a list?

A: 

Your question is fairly unclear. However, it sounds like you have a series of list objects that are being returned from a LINQ query, and you want to get some aggregates out of the values in all of those sub-lists. I haven't ever seen a way to do this in LINQ, and honestly I don't think the performance is likely to be that great even if there was a way to do it. The aggregates that you are looking for are pretty straightforward to calculate manually, with a loop. Something like this:

 double min = 200000000;
 double max = -200000000;
 double first = 0;
 double last = 0;
 bool hasFoundFirst = false;
 foreach ( List<double> childList in queryResults )
 {
      foreach ( double val in childList )
      {
           if ( !hasFoundFirst )
           {
                hasFoundFirst = true;
                first = val;
           }

           if ( val < min )
              min = val;
           if ( val > max )
              max = val;
           last = val;
      }
 }

Something like that would give you the results you are looking for in a very efficient way. This sort of thing, if you can code it efficiently, tends to be faster than LINQ. LINQ is great and I use it for many things, but it's just one tool among many.

x4000
+1  A: 

Hi, it is true that handcoded version will be a bit faster, but unless you know that performance is the key issue of your application, I wouldn't worry about that. The LINQ version of the code would look like this:

  IEnumerable<List<double>> queryResults = /*...*/

  var aggregates =
    from ds in queryResults
    select new {
      First = ds[0], Last = ds[ds.Count - 1],
      Lowest = ds.Min(), Highest = ds.Max() };

I think this is definitely easier to read :-). If the nested thing (ds) isn't of type List then you'll need to use First() and Last() extension methods instead of direct indexation.

Note that if you're interested in performance, you could also use Parallel LINQ, which runs the query on multiple threads. For short list, there is no real reason to do that, but if the collection is large, it may give you better performance (better than single-threaded hand-coded version).

Tomas Petricek