I have an interval partitioned into “MECE” subintervals, and I want to check which subinterval a number lies in.
(MECE stands for “mutually exclusive & collectively exhaustive”, meaning the partitions do not overlap and they leave no gaps in between.)
First I simply used if .. else if
:
; if (0/6 <= h && h < 1/6) { rgb = [c, x, 0] }
else if (1/6 <= h && h < 2/6) { rgb = [x, c, 0] }
else if (2/6 <= h && h < 3/6) { rgb = [0, c, x] }
else if (3/6 <= h && h < 4/6) { rgb = [0, x, c] }
else if (4/6 <= h && h < 5/6) { rgb = [x, 0, c] }
else if (5/6 <= h && h < 6/6) { rgb = [c, 0, x] }
Then I tried using the ternary operator:
rgb =
(0/6 <= h && h < 1/6) ? [c, x, 0] :
(1/6 <= h && h < 2/6) ? [x, c, 0] :
(2/6 <= h && h < 3/6) ? [0, c, x] :
(3/6 <= h && h < 4/6) ? [0, x, c] :
(4/6 <= h && h < 5/6) ? [x, 0, c] :
(5/6 <= h && h < 6/6) ? [c, 0, x] : [c, x, 0]
I also read about how object lookups are a more performant alternative to switch statements. Since I’m not checking the exact value of h
, I had to improvise:
rgb = ({
[`${(0/6 <= h && h < 1/6)}`]: [c, x, 0],
[`${(1/6 <= h && h < 2/6)}`]: [x, c, 0],
[`${(2/6 <= h && h < 3/6)}`]: [0, c, x],
[`${(3/6 <= h && h < 4/6)}`]: [0, x, c],
[`${(4/6 <= h && h < 5/6)}`]: [x, 0, c],
[`${(5/6 <= h && h < 6/6)}`]: [c, 0, x],
})['true']
The problem with object lookup is that there will be five keys of 'false'
, which is not good practice. So I wanted to use a similar lookup, but using ES6 native Map
class:
new Map([
[[0/6, 1/6], [c, x, 0]],
[[1/6, 2/6], [x, c, 0]],
[[2/6, 3/6], [0, c, x]],
[[3/6, 4/6], [0, x, c]],
[[4/6, 5/6], [x, 0, c]],
[[5/6, 6/6], [c, 0, x]],
]).forEach((value, key) => {
if (key[0] <= h && h < key[1]) rgb = value
})
Which is the most readable, maintainable, fastest-running way to achieve this? Are there any other options?
Math.floor(h*6)
as an index into some array, instead of these lengthy interval comparisons. – Doc Brown Mar 15 '19 at 21:38