如何映射在一些领域内的数(How to map a number in some ranges)

2019-10-30 00:07发布

我有一个范围值,如,例如, [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
}

这里所有的值是一个例子,我想,所有适用于任何其他值。

我不知道该怎么办了这一点。 我需要协助...

Answer 1:

尼娜肖尔茨的答案是错的。 她的规范化函数返回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 

正如你所看到的,边缘案件正确处理。 我们是如何得到这个答案?

  1. 首先,我们发现该范围的长度,该长度max - min + 1 。 所述+ 1 ,因为有在范围101层的元件是很重要的[0 - 100]以下。
  2. 接下来,我们得到的个数指标n在给定的范围(即n - min )。
  3. 然后,我们把指数n通过在范围内的元素的数目得到的范围内的值[0 - 1) 请注意, 1是不在范围内。
  4. 最后,我们乘以波段数这个数值并丢弃小数部分。 其结果是我们的索引。

请注意,如果该范围的长度不整除频带的数目,则第一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 

希望帮助。



Answer 2:

你可以采取一个公式,其中采取的范围内,所述槽,并返回一个归一化值。

由于范围,这是一个有点太长的(最后一个值包含在区间),你需要的最后一个值的检查,防止获取下一个值,通缉区间之外。

 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))); 



Answer 3:

您可以使用本机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); 



文章来源: How to map a number in some ranges