'Check numbers 0 to 1 but conditionally return value based on number unit in JS [closed]

In JS I have a function currently that uses the ternary operator, I need to check values for numbers between 0 to 1, but those numbers could have decimal places in them. So far I have done this:

  const checkNumbers = (e: any) => {
      const checkNum = e.value === 0 && e.value < 0.025 ? 'pink' :  e.value >= 0.025 && e.value < 0.050 ? 'blue' : e.value >= 0.050 && e.value < 0.075 ? 'yellow' : 'white'
      return  checkNum;
   }

So this currently checks the numbers between 0 - 0.075, but what if the numbers are 0.2, 0.3 etc, what I need to do it this way by adding more conditions? Or is there a better way to do it?



Solution 1:[1]

I'd do it by having an array that gives the upper bound of a range and the color for that range, then looping through the array to find the appropriate color. That way, you don't repeat values (which is always asking for double):

const colorRanges = [
    {max: 0.025, color: "pink"},
    {max: 0.05, color: "blue"},
    {max: 0.075, color: "yellow"},
    {max: Infinity, color: "white"}, // default
];
const checkNumbers = (e: any) => {
    const { value } = e;
    for (const {max, color} of colorRanges) {
        if (value < max) {
            return color;
        }
    }
    throw new Error(`Unexpectedly reached end of 'colorRanges' array for value ${value}`);
};

Live Example:

const colorRanges = [
    {max: 0.025, color: "pink"},
    {max: 0.05, color: "blue"},
    {max: 0.075, color: "yellow"},
    {max: Infinity, color: "white"}, // default
];
const checkNumbers = (e/*: any*/) => {
    const { value } = e;
    for (const {max, color} of colorRanges) {
        if (value < max) {
            return color;
        }
    }
    throw new Error(`Unexpectedly reached end of 'colorRanges' array for value ${value}`);
};

function test(value, expect) {
    const color = checkNumbers({value});
    console.log(`${value.toLocaleString()}: ${color} ${color === expect ? "Ok" : "***ERROR***"}`);
}

test(-42, "pink");
test(0, "pink");
test(0.0125, "pink");
test(0.0325, "blue");
test(0.06, "yellow");
test(0.08, "white");
test(7_123_412, "white");

Adding new ranges (like something to handle 0.2 or 0.3) is then just a matter of adding them in the relevant place in the array:

const colorRanges = [
    {max: 0.025, color: "pink"},
    {max: 0.05, color: "blue"},
    {max: 0.075, color: "yellow"},
    {max: 0.4, color: "fushia"}, // *** handles 0.2 and 0.3
    {max: Infinity, color: "white"}, // default
];

Solution 2:[2]

If all of your breakpoints are 0.025 apart, you could multiply e.value by 40, to make the breakpoints 1 apart. Then you could pull a corresponding index out of an array of colours.

const colours = ['pink', 'blue', 'yellow', 'white'];
const index = Math.floor(e.value * 40);
return colours[index] || 'white'; // fallback to white if something goes wrong

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 James