I've prepared an implementation of the median
free function:
/// Returns the "middle" of three values, when sorted in ascending order.
///
/// For example, the median of the first three prime numbers is:
///
/// median(2, 3, 5) //-> 3
/// median(2, 5, 3) //-> 3
/// median(3, 2, 5) //-> 3
/// median(3, 5, 2) //-> 3
/// median(5, 2, 3) //-> 3
/// median(5, 3, 2) //-> 3
///
/// Uses a stable sorting algorithm, which preserves the relative order
/// of arguments that compare equal. For example, `median(x, y, z)` is
/// always `y` clamped to `x...z`:
///
/// median(+0.0, -0.0, +0.0) //-> -0.0
/// median(-0.0, +0.0, -0.0) //-> +0.0
/// median(-0.0, -.infinity, +0.0) //-> -0.0
/// median(+0.0, -.infinity, -0.0) //-> +0.0
/// median(-0.0, +.infinity, +0.0) //-> +0.0
/// median(+0.0, +.infinity, -0.0) //-> -0.0
///
/// - Parameters:
/// - x: A value to compare.
/// - y: Another value to compare.
/// - z: A third value to compare.
public func median<T: Comparable>(_ x: T, _ y: T, _ z: T) -> T {
var (x, y, z) = (x, y, z)
// Compare (and swap) each pair of adjacent variables.
if x > y {
(x, y) = (y, x)
}
if y > z {
(y, z) = (z, y)
if x > y {
(x, y) = (y, x)
}
}
// Now `x` has the least value, and `z` has the greatest value.
return y
}
@kylemacomber @scanon
- Should
median
be part of this proposal, or a separate mini-proposal?
- Should it be overloaded to also accept a variable number of arguments?