Home > Back-end >  Create an incrementing / decrementing function that goes from 1 to 1, then 10 to 10, etc
Create an incrementing / decrementing function that goes from 1 to 1, then 10 to 10, etc

Time:07-26

I would like to create a function in plain JS that can increment or decrement by changing the increment or decrement value at each decade passage (which is my problem here)

For example: 0.1 -> 0.2 -> 0.3 -> 0.4 -> ... -> 1 -> 2 -> 3 -> ... -> 8 -> 9 -> 10 -> 20 -> 30 -> 40 -> ... -> 90 -> 100 -> 200 -> 300 -> etc.

or

0.8 -> 0.7 -> 0.6 ... -> 0.2 -> 0.1 -> 0.09 -> 0.08 -> 0.07 -> ... -> 0.02 -> 0.01 -> 0.009 -> 0.008 -> 0.007 -> etc.

Does someone have an idea on how to handle that?

CodePudding user response:

Look at the current value, then find where the value fits in with your range steps, add it to the step property.

function rangeFinder(ranges) {
  const keys = Array.from(ranges)
  keys.sort(function(a, b) {
    return Number(a) - Number(b)
  })
  return function(val) {
    let key = null
    const len = keys.length
    for (let i = 0; i < len; i  ) {
      if (key === null || keys[i] < val) {
        key = Math.max(key, keys[i])
      }
    }
    return key
  }
}

const ranges = [
  '.000001',
  '.00001',
  '.0001',
  '.001',
  '.01',
  '.1',
  '1',
  '10',
  '100',
  '1000'
]

const input = document.querySelector('[type="number"]')
input.oninput = function() {
  const value = Number(this.value)
  const range = rangeFinder(ranges)(value)

  input.setAttribute('step', range)

  console.log(value, range, value   range)
}
<input type="number" min="0.000000" max="10000" value="0.000000" step=".000001">

CodePudding user response:

I would use math to get the increment appropriate for the number.

The rounding issue that Barmar mentioned is taken care of by performing the addition, creating a string of the required precision (here only 1 because there is only 1 significant digit, but that would need to change if there were more), and then parsing it as a new float.

function getIncrement(num) {
  let abs = Math.abs(num);
  let inc = Math.pow(10, Math.floor(Math.log10(abs)));
  if (abs === num) return inc;
  return -inc;
}

let x = 0.1;
let out = [x];
while (x < 1000) {
  x = parseFloat((x   getIncrement(x)).toPrecision(1));
  out.push(x);
}

console.log(out);

  • Related