I have a collection of person objects (IEnumerable) and each person has an age property.
I want to generate stats on the collection such as Max, Min, Average, Median, etc on this age property.
What is the most elegant way of doing this using LINQ?
It is slightly slowerLINQ syntax is typically less efficient than a foreach loop. It's good to be aware of any performance tradeoff that might occur when you use LINQ to improve the readability of your code. And if you'd like to measure the performance difference, you can use a tool like BenchmarkDotNet to do so.
var sum = (from temp in list select temp). Sum(); var percentage = from temp in list select temp/sum *100; the above one is optimized linq query. var percentage = from temp in list select (temp / list.
Revised on May 23, 2022. The median is the value that's exactly in the middle of a dataset when it is ordered. It's a measure of central tendency that separates the lowest 50% from the highest 50% of values. The steps for finding the median differ depending on whether you have an odd or an even number of data points.
Here is a complete, generic implementation of Median that properly handles empty collections and nullable types. It is LINQ-friendly in the style of Enumerable.Average, for example:
double? medianAge = people.Median(p => p.Age);
This implementation returns null when there are no non-null values in the collection, but if you don't like the nullable return type, you could easily change it to throw an exception instead.
public static double? Median<TColl, TValue>( this IEnumerable<TColl> source, Func<TColl, TValue> selector) { return source.Select<TColl, TValue>(selector).Median(); } public static double? Median<T>( this IEnumerable<T> source) { if(Nullable.GetUnderlyingType(typeof(T)) != null) source = source.Where(x => x != null); int count = source.Count(); if(count == 0) return null; source = source.OrderBy(n => n); int midpoint = count / 2; if(count % 2 == 0) return (Convert.ToDouble(source.ElementAt(midpoint - 1)) + Convert.ToDouble(source.ElementAt(midpoint))) / 2.0; else return Convert.ToDouble(source.ElementAt(midpoint)); }
var max = persons.Max(p => p.age); var min = persons.Min(p => p.age); var average = persons.Average(p => p.age);
Fix for median in case of even number of elements
int count = persons.Count(); var orderedPersons = persons.OrderBy(p => p.age); float median = orderedPersons.ElementAt(count/2).age + orderedPersons.ElementAt((count-1)/2).age; median /= 2;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With