Как отобразить число в некоторых диапазонах - PullRequest
0 голосов
/ 11 июня 2019

У меня есть диапазон значений, таких как, например, [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
}

Все значения здесь являются примерами, я хочу, чтобы все работало с любыми другими значениями.

Я не знаю, как это сделать.Мне нужна помощь ...

Ответы [ 3 ]

2 голосов
/ 11 июня 2019

Вы можете взять формулу, которая берет диапазон и интервал и возвращает нормализованное значение.

Из-за слишком длинного диапазона (последнее значение входит в интервал), вам необходимо проверить последнее значение и предотвратить получение следующего значения за пределами требуемого интервала.

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)));
2 голосов
/ 14 июня 2019

Ответ Нины Шольц неверен.Ее функция нормализации возвращает 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 важно, поскольку в диапазоне [0 - 100] включительно 101 элемент.
  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

Надеюсь, это поможет.

1 голос
/ 11 июня 2019

Вы можете использовать встроенную функцию 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);
...