我有一组人物对象(IEnumerable),每个人都有一个年龄属性.
我想在这个年龄属性上生成集合的统计数据,例如Max,Min,Average,Median等.
使用LINQ最优雅的方法是什么?
Ran*_*ard 34
这是一个完整的,通用的Median实现,可以正确处理空集合和可空类型.它是Enumerable.Average风格的LINQ友好的,例如:
double? medianAge = people.Median(p => p.Age);
Run Code Online (Sandbox Code Playgroud)
当集合中没有非空值时,此实现返回null,但如果您不喜欢可为空的返回类型,则可以轻松地将其更改为抛出异常.
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));
}
Run Code Online (Sandbox Code Playgroud)
Ita*_*aro 28
var max = persons.Max(p => p.age);
var min = persons.Min(p => p.age);
var average = persons.Average(p => p.age);
Run Code Online (Sandbox Code Playgroud)
在偶数个元素的情况下修复中值
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;
Run Code Online (Sandbox Code Playgroud)
Ali*_*tad 10
Max,Min,Average是Linq的一部分:
int[] ints = new int[]{3,4,5};
Console.WriteLine(ints.Max());
Console.WriteLine(ints.Min());
Console.WriteLine(ints.Average());
Run Code Online (Sandbox Code Playgroud)
中位数很容易:
UPDATE
我添加了订单:
ints.OrderBy(x=>x).Skip(ints.Count()/2).First();
Run Code Online (Sandbox Code Playgroud)
谨防
所有这些操作都是循环完成的.例如,ints.Count()是一个循环,所以如果你已经获得了ints.Length并存储到一个变量或只是按原样使用它,那就更好了.
int count = persons.Count();
if (count % 2 == 0)
var median = persons.Select(x => x.Age).OrderBy(x => x).Skip((count / 2) - 1).Take(2).Average();
else
var median = persons.Select(x => x.Age).OrderBy(x => x).ElementAt(count / 2);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
13321 次 |
最近记录: |