Rory Claasen

Linq Median

1 min read

Extension methods for calculating the median a sequence of numbers. Similar to Linq Product, this is using the INumber interface from Generic Math.

MedianExtensions.cs
public static TNumber Median<TNumber>(this IEnumerable<TNumber> source) where TNumber : struct, INumber<TNumber>
=> Median(new ReadOnlySpan<TNumber>(source.ToArray()));
public static TNumber Median<TNumber>(this TNumber[] source) where TNumber : struct, INumber<TNumber>
=> Median(new ReadOnlySpan<TNumber>(source));
public static TNumber Median<TNumber>(this ReadOnlySpan<TNumber> source) where TNumber : struct, INumber<TNumber>
{
if (source.IsEmpty)
{
return TNumber.Zero;
}
if (source.Length == 1)
{
return source[0];
}
if (source.Length == 2)
{
checked
{
return (source[0] + source[1]) / TNumber.CreateChecked(2);
}
}
var sourceCopy = new Span<TNumber>(source.ToArray());
MemoryExtensions.Sort(sourceCopy);
checked
{
if (sourceCopy.Length % 2 == 0)
{
return (sourceCopy[sourceCopy.Length / 2] + sourceCopy[(sourceCopy.Length / 2) - 1]) / TNumber.CreateChecked(2);
}
return sourceCopy[sourceCopy.Length / 2];
}
}