1. ホーム
  2. swift

[解決済み] Swift で 2 つの値の間の数値を「クランプ」する標準的な方法

2023-06-08 04:12:34

質問

与えられた。

let a = 4.2
let b = -1.3
let c = 6.4

これらの値を与えられた範囲にクランプする最も簡単で迅速な方法を知りたいのですが、例えば 0...5 というように。

a -> 4.2
b -> 0
c -> 5

以下のようなことができるのは知っています。

let clamped = min(max(a, 0), 5)

みたいな感じか。

let clamped = (a < 0) ? 0 : ((a > 5) ? 5 : a)

しかし、私はSwiftでこれを行うための他の方法があるかどうか疑問に思っていました。特に、Swiftで数値をクランプすることについての質問がないように見えるので、私は、この目的のために特に意図されたSwift標準ライブラリに何かあるかどうかを知りたいです(そしてSOで文書化します)。

ないかもしれません、そして、もしそうなら、それはまた、私が喜んで受け入れる答えです。

どのように解決するのですか?

スウィフト4/5

の拡張 Comparable/Strideable と同様に ClosedRange.clamped(to:_) -> ClosedRange というように、Swiftの標準ライブラリにある

extension Comparable {
    func clamped(to limits: ClosedRange<Self>) -> Self {
        return min(max(self, limits.lowerBound), limits.upperBound)
    }
}

#if swift(<5.1)
extension Strideable where Stride: SignedInteger {
    func clamped(to limits: CountableClosedRange<Self>) -> Self {
        return min(max(self, limits.lowerBound), limits.upperBound)
    }
}
#endif

使用方法です。

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