Given:
let a = 4.2
let b = -1.3
let c = 6.4
I want to know the simplest, Swiftiest way to clamp these values to a given range, say 0...5
, such that:
a -> 4.2
b -> 0
c -> 5
I know I can do the following:
let clamped = min(max(a, 0), 5)
Or something like:
let clamped = (a < 0) ? 0 : ((a > 5) ? 5 : a)
But I was wondering if there were any other ways to do this in Swift—in particular, I want to know (and document on SO, since there doesn't appear to be a question about clamping numbers in Swift) whether there is anything in the Swift standard library intended specifically for this purpose.
There may not be, and if so, that's also an answer I'll happily accept.
Swift 4/5
Extension of Comparable/Strideable
similar to ClosedRange.clamped(to:_) -> ClosedRange
from standard Swift library.
extension Comparable {
func clamped(to limits: ClosedRange<Self>) -> Self {
return min(max(self, limits.lowerBound), limits.upperBound)
}
}
// Swift < 5.1
extension Strideable where Stride: SignedInteger {
func clamped(to limits: CountableClosedRange<Self>) -> Self {
return min(max(self, limits.lowerBound), limits.upperBound)
}
}
Usage:
15.clamped(to: 0...10) // returns 10
3.0.clamped(to: 0.0...10.0) // returns 3.0
"a".clamped(to: "g"..."y") // returns "g"
// this also works (thanks to Strideable extension)
let range: CountableClosedRange<Int> = 0...10
15.clamped(to: range) // returns 10