Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return best fit item from collection in C# 3.5 in just a line or two

Tags:

c#

linq

max

Here is some sample code I have basically written thousands of times in my life:

// find bestest thingy
Thing bestThing;
float bestGoodness = FLOAT_MIN;
foreach( Thing x in arrayOfThings )
{
  float goodness = somefunction( x.property, localvariable );
  if( goodness > bestGoodness )
  {
    bestGoodness = goodness;
    bestThing = x;
  }
}
return bestThing;

And it seems to me C# should already have something that does this in just a line. Something like:

return arrayOfThings.Max( delegate(x)
  { return somefunction( x.property, localvariable ); });

But that doesn't return the thing (or an index to the thing, which would be fine), that returns the goodness-of-fit value.

So maybe something like:

var sortedByGoodness = from x in arrayOfThings 
  orderby somefunction( x.property, localvariable ) ascending 
  select x;
return x.first;

But that's doing a whole sort of the entire array and could be too slow.

Does this exist?

like image 367
Jamie Fristrom Avatar asked Mar 22 '12 00:03

Jamie Fristrom


1 Answers

This is what you can do using System.Linq:

var value = arrayOfThings
    .OrderByDescending(x => somefunction(x.property, localvariable))
    .First();

If the array can be empty, use .FirstOrDefault(); to avoid exceptions.

You really don't know how this is implemented internally, so you can't assure this will sort the whole array to get the first element. For example, if it was linq to sql, the server would receive a query including the sort and the condition. It wouldn't get the array, then sort it, then get the first element.

In fact, until you don't call First, the first part of the query isn't evaluated. I mean this isn't a two steps evaluation, but a one step evaluation.

var sortedValues =arrayOfThings
  .OrderByDescending(x => somefunction(x.property, localvariable));
// values isn't still evaluated
var value = sortedvalues.First();
// the whole expression is evaluated at this point.
like image 154
JotaBe Avatar answered Nov 01 '22 21:11

JotaBe