如何在某些范围内映射数字
How to map a number in some ranges
我有一个值的范围,例如 [0, 100] = [minValue, maxValue]
和波段数,例如 BANDS_NUMBER = 5
。
所以我可以获得这些波段:
[0 - 20]
[21 - 40]
[41 - 60]
[61 - 80]
[81 - 100]
然后我想在每个范围关联一个比例值:
i: 0 --> [0 - 20] --> 0.2
i: 1 --> [21 - 40] --> 0.4
i: 2 --> [41 - 60] --> 0.6
i: 3 --> [61 - 80] --> 0.8
i: 4 --> [81 - 100] --> 1
此值按以下方式计算:(i + 1) / BANDS_NUMBER
其中 i
是假设循环的索引。
然后我有一个输入 n
其值在 [minValue, maxValue] = [0, 100]
.
范围内
我要的是这个数字相关的比例值。
因此,例如,如果:
n = 0 --> scaleValue = 0.2
n = 10 --> scaleValue = 0.2
n = 20 --> scaleValue = 0.2
n = 35 --> scaleValue = 0.4
n = 68 --> scaleValue = 0.8
n = 99 --> scaleValue = 1
...
如何创建这样的函数?我想象一个这样的函数:
function map(n, minValue, maxValue, bandsNumber) {
const scaleValue = ...
return scaleValue
}
这里的所有值都是示例,我希望所有值都适用于任何其他值。
我不知道该怎么做。我需要一些帮助...
您可以使用本机 Array.map
函数来映射每个值。
像这样:
const vals = [
[0, 20],
[21, 40],
[41, 60],
[61, 80],
[81, 100],
];
const BANDS_NUMBER = 5;
const result = vals.map((range, index) => (index + 1) / BANDS_NUMBER);
console.log(result);
您可以采用一个公式,该公式采用范围和槽,returns 是一个标准化值。
由于范围有点太长(最后一个值包含在间隔中),您需要检查最后一个值并防止获取下一个值,超出所需的间隔。
function normalize(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 1
console.log(...[0, 10, 20, 35, 68, 99, 100].map(normalize.bind(null, 0, 100, 5)));
Nina Scholz 的 是错误的。她的标准化函数 returns 0.4
而不是 0.2
用于值 20
:
function normalize(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
因为 20
在第一波段,它的值应该是 0.2
:
i: 0 --> [0 - 20] --> 0.2
i: 1 --> [21 - 40] --> 0.4
i: 2 --> [41 - 60] --> 0.6
i: 3 --> [61 - 80] --> 0.8
i: 4 --> [81 - 100] --> 1
正确答案是:
const index = (min, max, bands, n) =>
Math.floor(bands * (n - min) / (max - min + 1));
const band = n => index(0, 100, 5, n);
console.log(band(0), band(20)); // 0 0
console.log(band(21), band(40)); // 1 1
console.log(band(41), band(60)); // 2 2
console.log(band(61), band(80)); // 3 3
console.log(band(81), band(100)); // 4 4
如您所见,边缘情况得到了正确处理。我们是如何得到这个答案的?
- 首先,我们找到范围的长度
max - min + 1
。 + 1
很重要,因为 [0 - 100]
范围内有 101 个元素(含)。
- 接下来,我们得到给定范围内数字
n
的索引(即n - min
)。
- 然后,我们将
n
的索引除以范围内的元素个数,得到范围[0 - 1)
内的值。请注意 1
不在范围内。
- 最后,我们将这个值乘以波段数并舍弃小数部分。结果就是我们的索引。
请注意,如果范围的长度不能被波段数整除,那么第一个 x
个波段将有一个附加元素,其中 x
是除以波段长度的余数波段数的范围。
最后,我们可以通过将结果索引递增然后除以波段数来获得您想要的值:
const index = (min, max, bands, n) =>
Math.floor(bands * (n - min) / (max - min + 1));
const value = (min, max, bands, n) =>
(index(min, max, bands, n) + 1) / bands;
const result = n => value(0, 100, 5, n);
console.log(result(0), result(20)); // 0.2 0.2
console.log(result(21), result(40)); // 0.4 0.4
console.log(result(41), result(60)); // 0.6 0.6
console.log(result(61), result(80)); // 0.8 0.8
console.log(result(81), result(100)); // 1 1
希望对您有所帮助。
我有一个值的范围,例如 [0, 100] = [minValue, maxValue]
和波段数,例如 BANDS_NUMBER = 5
。
所以我可以获得这些波段:
[0 - 20]
[21 - 40]
[41 - 60]
[61 - 80]
[81 - 100]
然后我想在每个范围关联一个比例值:
i: 0 --> [0 - 20] --> 0.2
i: 1 --> [21 - 40] --> 0.4
i: 2 --> [41 - 60] --> 0.6
i: 3 --> [61 - 80] --> 0.8
i: 4 --> [81 - 100] --> 1
此值按以下方式计算:(i + 1) / BANDS_NUMBER
其中 i
是假设循环的索引。
然后我有一个输入 n
其值在 [minValue, maxValue] = [0, 100]
.
我要的是这个数字相关的比例值。 因此,例如,如果:
n = 0 --> scaleValue = 0.2
n = 10 --> scaleValue = 0.2
n = 20 --> scaleValue = 0.2
n = 35 --> scaleValue = 0.4
n = 68 --> scaleValue = 0.8
n = 99 --> scaleValue = 1
...
如何创建这样的函数?我想象一个这样的函数:
function map(n, minValue, maxValue, bandsNumber) {
const scaleValue = ...
return scaleValue
}
这里的所有值都是示例,我希望所有值都适用于任何其他值。
我不知道该怎么做。我需要一些帮助...
您可以使用本机 Array.map
函数来映射每个值。
像这样:
const vals = [
[0, 20],
[21, 40],
[41, 60],
[61, 80],
[81, 100],
];
const BANDS_NUMBER = 5;
const result = vals.map((range, index) => (index + 1) / BANDS_NUMBER);
console.log(result);
您可以采用一个公式,该公式采用范围和槽,returns 是一个标准化值。
由于范围有点太长(最后一个值包含在间隔中),您需要检查最后一个值并防止获取下一个值,超出所需的间隔。
function normalize(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 1
console.log(...[0, 10, 20, 35, 68, 99, 100].map(normalize.bind(null, 0, 100, 5)));
Nina Scholz 的 0.4
而不是 0.2
用于值 20
:
function normalize(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
因为 20
在第一波段,它的值应该是 0.2
:
i: 0 --> [0 - 20] --> 0.2
i: 1 --> [21 - 40] --> 0.4
i: 2 --> [41 - 60] --> 0.6
i: 3 --> [61 - 80] --> 0.8
i: 4 --> [81 - 100] --> 1
正确答案是:
const index = (min, max, bands, n) =>
Math.floor(bands * (n - min) / (max - min + 1));
const band = n => index(0, 100, 5, n);
console.log(band(0), band(20)); // 0 0
console.log(band(21), band(40)); // 1 1
console.log(band(41), band(60)); // 2 2
console.log(band(61), band(80)); // 3 3
console.log(band(81), band(100)); // 4 4
如您所见,边缘情况得到了正确处理。我们是如何得到这个答案的?
- 首先,我们找到范围的长度
max - min + 1
。+ 1
很重要,因为[0 - 100]
范围内有 101 个元素(含)。 - 接下来,我们得到给定范围内数字
n
的索引(即n - min
)。 - 然后,我们将
n
的索引除以范围内的元素个数,得到范围[0 - 1)
内的值。请注意1
不在范围内。 - 最后,我们将这个值乘以波段数并舍弃小数部分。结果就是我们的索引。
请注意,如果范围的长度不能被波段数整除,那么第一个 x
个波段将有一个附加元素,其中 x
是除以波段长度的余数波段数的范围。
最后,我们可以通过将结果索引递增然后除以波段数来获得您想要的值:
const index = (min, max, bands, n) =>
Math.floor(bands * (n - min) / (max - min + 1));
const value = (min, max, bands, n) =>
(index(min, max, bands, n) + 1) / bands;
const result = n => value(0, 100, 5, n);
console.log(result(0), result(20)); // 0.2 0.2
console.log(result(21), result(40)); // 0.4 0.4
console.log(result(41), result(60)); // 0.6 0.6
console.log(result(61), result(80)); // 0.8 0.8
console.log(result(81), result(100)); // 1 1
希望对您有所帮助。