Reputation: 37
I have the following: (C# code, VS2013)
class DailyTemp
{
public int Day;
public int LowTemp;
public int HighTemp;
}
List<DailyTemp> dailyTemps = new List<DailyTemp>();
//I fill this list with DailyTemp objects
My questions is, how do I write a lambda expression to go through my list and return the day that has the smallest difference between high and low temps? Thank you for your time.
Upvotes: 0
Views: 1860
Reputation: 4619
Try:
return dailyTemps.OrderBy(dt => dt.HighTemp - dt.LowTemp).Select(dt => dt.Day).First();
As noted by @Colin DeClue, it's more efficient to call Select
before First
so that we're retrieving the minimum needed information from the data source (which can matter on larger data sets coming from a DB).
Upvotes: 9
Reputation: 126814
If you want to do an approach with a single pass over the sequence and using built-in methods, you can leverage Enumerable.Aggregate
and keep the argument with the lowest temperature difference, discarding the other.
Func<DailyTemp, int> tempDiff = x => x.HighTemp - x.LowTemp;
var day = dailyTemps.Aggregate((a, b) => tempDiff(a) < tempDiff(b) ? a : b);
Otherwise, MoreLinq's MinBy
might read simpler (externally available API), as well as the OrderBy
method available within the BCL (that requires sorting), each approach being highlighted in other visible answers.
Upvotes: 2
Reputation: 203823
We can use the MinBy method of MoreLINQ (argument validation removed below) to get the min value of a collection based on the value of a selector:
public static TSource MinBy<TSource, TKey>(this IEnumerable<TSource> source,
Func<TSource, TKey> selector)
{
return source.MinBy(selector, Comparer<TKey>.Default);
}
public static TSource MinBy<TSource, TKey>(this IEnumerable<TSource> source,
Func<TSource, TKey> selector, IComparer<TKey> comparer)
{
using (IEnumerator<TSource> sourceIterator = source.GetEnumerator())
{
if (!sourceIterator.MoveNext())
{
throw new InvalidOperationException("Sequence was empty");
}
TSource min = sourceIterator.Current;
TKey minKey = selector(min);
while (sourceIterator.MoveNext())
{
TSource candidate = sourceIterator.Current;
TKey candidateProjected = selector(candidate);
if (comparer.Compare(candidateProjected, minKey) < 0)
{
min = candidate;
minKey = candidateProjected;
}
}
return min;
}
}
This lets us write:
var day = dailyTemps.MinBy(dt => dt.HighTemp - dt.LowTemp);
Upvotes: 0