How To Map A Number In Some Ranges
Solution 1:
You could take a formula, which take the range and the slot and returns a normalized value.
Because of the range, which is a bit too long (the last value is included in the interval), you need a check for the last value and prevent getting the next value, outside of the wanted interval.
functionnormalize(min, max, bands, n) {
return n === max
? 1
: Math.floor(1 + ((n - min) / (max - min)) * bands) / bands;
}
// 0.2 0.2 0.4 0.4 0.8 1 1console.log(...[0, 10, 20, 35, 68, 99, 100].map(normalize.bind(null, 0, 100, 5)));
Solution 2:
Nina Scholz's answer is wrong. Her normalize function returns 0.4
instead of 0.2
for the value 20
:
functionnormalize(min, max, bands, n) {
return n === max
? 1
: Math.floor(1 + ((n - min) / (max - min)) * bands) / bands;
}
console.log(normalize(0, 100, 5, 20)); // expected 0.2, actual 0.4
Because 20
is in the first band, it should have the value 0.2
:
i: 0 --> [0 - 20] --> 0.2i: 1 --> [21 - 40] --> 0.4i: 2 --> [41 - 60] --> 0.6i: 3 --> [61 - 80] --> 0.8i: 4 --> [81 - 100] --> 1
The correct answer is:
constindex = (min, max, bands, n) =>
Math.floor(bands * (n - min) / (max - min + 1));
constband = n => index(0, 100, 5, n);
console.log(band(0), band(20)); // 0 0console.log(band(21), band(40)); // 1 1console.log(band(41), band(60)); // 2 2console.log(band(61), band(80)); // 3 3console.log(band(81), band(100)); // 4 4
As you can see, the edge cases are handled correctly. How did we get to this answer?
- First, we find the length of the range which is
max - min + 1
. The+ 1
is important because there are 101 elements in the range[0 - 100]
inclusive. - Next, we get the index of the number
n
in the given range (i.e.n - min
). - Then, we divide the index of
n
by the number of elements in the range to get a value in the range[0 - 1)
. Note that1
is not in the range. - Finally, we multiply this value by the number of bands and discard the fractional part. The result is our index.
Note that if the length of the range is not divisible by the number of bands then the first x
bands will have one additional element, where x
is the remainder of dividing the length of the range by the number of bands.
Finally, we can get the value you want by incrementing the resulting index and then dividing it by the number of bands:
constindex = (min, max, bands, n) =>
Math.floor(bands * (n - min) / (max - min + 1));
constvalue = (min, max, bands, n) =>
(index(min, max, bands, n) + 1) / bands;
constresult = n => value(0, 100, 5, n);
console.log(result(0), result(20)); // 0.2 0.2console.log(result(21), result(40)); // 0.4 0.4console.log(result(41), result(60)); // 0.6 0.6console.log(result(61), result(80)); // 0.8 0.8console.log(result(81), result(100)); // 1 1
Hope that helps.
Solution 3:
You can use a native Array.map
function to map each value.
Something like this:
const vals = [
[0, 20],
[21, 40],
[41, 60],
[61, 80],
[81, 100],
];
constBANDS_NUMBER = 5;
const result = vals.map((range, index) => (index + 1) / BANDS_NUMBER);
console.log(result);
Post a Comment for "How To Map A Number In Some Ranges"