swift range greater than lower bound
Rather than create a new type of range you can instead create a method that will identify values above the lower bound:
extension ClosedRange {
func containsAboveLowerBound(value:Bound) -> Bool {
if value > self.lowerBound {
return self.contains(value)
}
else {
return false
}
}
}
implementing it like so:
let r = 2.0...3.0
r.containsAboveLowerBound(value: 2.0) // false
r.containsAboveLowerBound(value: 2.01) // true
nextUp
from the FloatingPoint
protocol
You can make use of the nextUp
property of Double
, as blueprinted in the FloatingPoint
protocol to which Double
conforms
nextUp
The least representable value that compares greater than this value.
For any finite value
x
,x.nextUp
is greater thanx
. ...
I.e.:
let uptoTwo = 0.0...2.0
let twoPlus = 2.0.nextUp...4.0
The property ulp
, also blueprinted in the FloatingPoint
protocol, has been mentioned in the comments to your question. For most numbers, this is the difference between self
and the next greater representable number:
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 numbersx
, this is the difference betweenx
and the next greater (in magnitude) representable number. ...
nextUp
does, in essence, return the value of self
with the addition of ulp
. So for your example above, the following is equivalent (whereas, imo, nextup
should be preferred in this use case).
let uptoTwo = 0.0...2.0
let twoPlus = (2.0+2.0.ulp)...4.0
You might also want to consider replacing the lower bound literal in twoPlus
with the upperBound
property of the preceding uptoTwo
range:
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!
If your actual purpose is to use ranges for filtering, how about making them as closures?
let underTen = {0.0 <= $0 && $0 < 10.0}
let upToTwo = {0.0 <= $0 && $0 <= 2.0}
let twoPlus = {2.0 < $0 && $0 <= 4.0}
You can use such filtering closures like this:
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($0.experience)}
print(filteredUnderTen) //->[Client(1.0), Client(2.0), Client(3.0)]
let filteredUpToTwo = clients.filter {upToTwo($0.experience)}
print(filteredUpToTwo) //->[Client(1.0), Client(2.0)]
let filteredTwoPlus = clients.filter {twoPlus($0.experience)}
print(filteredTwoPlus) //->[Client(3.0)]