Reputation: 25
Hello im trying to write a function that compares to ranges and returns the value of the first range in the second.
Example : Range A is (22.0..24.0) Range B ( 20.0..26.0)
so in that case the return value should be 2.0
if Range B is (23.0..26.0) it should return 1.0
How can i do this?
Upvotes: 1
Views: 2528
Reputation: 18557
What you're doing here is taking the intersection (overlap) of two ranges, and calculating its size. So, building on what Adam Millerchip and cactustictacs have already done, I think I'd break the problem down into simpler parts: min
, max
, and size
properties for a range, and an intersect
function that calculates the common subrange of two ranges (if there is one):
val ClosedFloatingPointRange<Double>.min
get() = minOf(start, endInclusive)
val ClosedFloatingPointRange<Double>.max
get() = maxOf(start, endInclusive)
val ClosedFloatingPointRange<Double>.size
get() = max - min
infix fun ClosedFloatingPointRange<Double>.intersect(other: ClosedFloatingPointRange<Double>)
= if (min <= other.max && other.min <= max)
maxOf(min, other.min).rangeTo(minOf(max, other.max))
else
null
With those, you can do e.g.:
val a = 22.0 .. 24.0
val b = 20.0 .. 26.0
println(a intersect b)
println((a intersect b)?.size)
Having the size explicit and separate from the intersection makes each one easier to understand, easier to test, and easier to reuse. And having intersect
return null if there's no overlap is safer.
(This should work for negative numbers and for descending ranges; the intersection is always given as ascending. This assumes Double
ranges; it could be made to handle other types too, though the type parameters get messy.)
TBH, I'm a little surprised that none of those are in the standard library…
Upvotes: 3
Reputation: 1364
Ok well
Range
some what act as a list so the the could do like
val r1 = (22.0)..(25.0)
val r2 = (23.0)..(30.0)
val findRangeOfFirstElement = (r1.start -r2.start)
Upvotes: -1
Reputation: 23091
You could write a function like this:
fun ClosedRange<Double>.containedIn(other: ClosedRange<Double>) =
(min(endInclusive, other.endInclusive) - max(start, other.start))
.coerceAtLeast(0.0)
And then use it like this:
val rangeA = 22.0..24.0
val rangeB = 20.0..26.0
val rangeC = 23.0..26.0
println(rangeA.containedIn(rangeB))
println(rangeA.containedIn(rangeC))
Result:
2.0
1.0
Note: you should also import the min
/max
functions:
import kotlin.math.max
import kotlin.math.min
Upvotes: 5