swift 范围大于下限

swift range greater than lower bound

我需要像这样实现体验过滤器

在swift范围内如何表示?

问题是我不能表达超过 2 到 4 年。虽然我可以做的少于上限。例如像这样

let underTen = 0.0..<10.0

我需要这样的东西(大于下限)

let uptoTwo = 0.0...2.0
let twoPlus = 2.0>..4.0  // compiler error

目前我在做

let twoPlus = 2.1...4.0

但这并不完美。

如果您的实际目的是使用 ranges 进行过滤,将它们作为闭包怎么样?

let underTen = {0.0 <= [=10=] && [=10=] < 10.0}
let upToTwo = {0.0 <= [=10=] && [=10=] <= 2.0}
let twoPlus = {2.0 <  [=10=] && [=10=] <= 4.0}

您可以像这样使用这样的过滤闭包

class Client: CustomStringConvertible {
    var experience: Double
    init(experience: Double) {self.experience = experience}
    var description: String {return "Client(\(experience))"}
}
let clients = [Client(experience: 1.0),Client(experience: 2.0),Client(experience: 3.0)]
let filteredUnderTen = clients.filter {underTen([=11=].experience)}
print(filteredUnderTen) //->[Client(1.0), Client(2.0), Client(3.0)]
let filteredUpToTwo = clients.filter {upToTwo([=11=].experience)}
print(filteredUpToTwo) //->[Client(1.0), Client(2.0)]
let filteredTwoPlus = clients.filter {twoPlus([=11=].experience)}
print(filteredTwoPlus) //->[Client(3.0)]

您可以创建一种方法来识别高于下限的值,而不是创建一种新的范围类型:

extension ClosedRange {
    func containsAboveLowerBound(value:Bound) -> Bool {
        if value > self.lowerBound {
            return self.contains(value)
        }
        else {
            return false
        }
    }
}

像这样实现它:

let r = 2.0...3.0
r.containsAboveLowerBound(value: 2.0) // false
r.containsAboveLowerBound(value: 2.01) // true

nextUp 来自 FloatingPoint 协议

您可以使用 Double 符合

nextUp property of Double, as blueprinted in the FloatingPoint protocol

nextUp

The least representable value that compares greater than this value.

For any finite value x, x.nextUp is greater than x. ...

即:

let uptoTwo = 0.0...2.0
let twoPlus = 2.0.nextUp...4.0

属性 ulp,也在 FloatingPoint 协议中进行了蓝图,已在您的问题的评论中提到。对于大多数数字,这是 self 和下一个更大的可表示数字之间的差异:

ulp

The unit in the last place of self.

This is the unit of the least significant digit in the significand of self. For most numbers x, this is the difference between x and the next greater (in magnitude) representable number. ...

nextUp 本质上是 return self 的值加上 ulp。因此,对于上面的示例,以下内容是等效的(而在此用例中,imo,nextup 应该是首选)。

let uptoTwo = 0.0...2.0 
let twoPlus = (2.0+2.0.ulp)...4.0

您可能还需要考虑将 twoPlus 中的下限文字替换为前面 uptoTwo 范围的 upperBound 属性:

let uptoTwo = 0.0...2.0                       // [0, 2] closed-closed
let twoPlus = uptoTwo.upperBound.nextUp...4.0 // (2, 4] open-closed

if uptoTwo.overlaps(twoPlus) {
    print("the two ranges overlap ...")
}
else {
    print("ranges are non-overlapping, ok!")
}
// ranges are non-overlapping, ok!

我觉得可以,

extension ClosedRange where Bound == Int {
    func containsExclusiveOfBounds(_ bound: Bound) -> Bool {
        return !(bound == lowerBound || bound == upperBound)
    }
}