Extension methods for calculating the median a sequence of numbers. Similar to Linq Product, this is using the INumber interface from Generic Math.
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]; }}