一尘不染

在Swift中将数字“限制”在两个值之间的标准方法

swift

鉴于:

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中是否还有其他方法可以做到这一点-
特别是,我想知道(并在SO上进行文档记录,因为在Swift中似乎没有关于夹紧数字的问题)中是否包含任何内容。 Swift标准库专门用于此目的。

可能没有,如果是的话,那也是我很乐意接受的答案。:)


阅读 319

收藏
2020-07-07

共1个答案

一尘不染

ClosedInterval类型已经有一个

func clamp(_ intervalToClamp: ClosedInterval<Bound>) -> ClosedInterval<Bound>

以另一个 间隔 作为参数的方法。Swift Evolution邮件列表上有一个建议

添加另一种将 单个值 钳位到给定间隔的方法:

/// Returns `value` clamped to `self`.
func clamp(value: Bound) -> Bound

而这正是您所需要的。

使用现有clamp()方法的实现在

例如,此附加clamp()方法可以实现为

extension ClosedInterval {
    func clamp(value : Bound) -> Bound {
        return self.start > value ? self.start
            : self.end < value ? self.end
            : value
    }
}

例:

(0.0 ... 5.0).clamp(4.2)    // 4.2
(0.0 ... 5.0).clamp(-1.3)   // 0.0
(0.0 ... 5.0).clamp(6.4)    // 5.0

ClosedInterval通用 类型

public struct ClosedInterval<Bound : Comparable> { ... }

因此,该工程不仅为Double但这些都是类型Comparable(如IntCGFloatString,…):

(1 ... 3).clamp(10)      // 3
("a" ... "z").clamp("ä") // "ä"

Swift 3(Xcode 8)的 更新
ClosedInterval已重命名为ClosedRange,其属性lower/upperBound现在为:

extension ClosedRange {
    func clamp(_ value : Bound) -> Bound {
        return self.lowerBound > value ? self.lowerBound
            : self.upperBound < value ? self.upperBound
            : value
    }
}
2020-07-07