skip to Main Content

I want to create an array of 9 values as result, where i have written a function which takes the min and max value

function generateSequence(min, max, numElements = 9) {
  // Step 1: Calculate the raw step size
  let step = (max - min) / (numElements - 3); // One value below min, and one above max
  
  // Step 2: Dynamically determine the rounding factor based on the step size
  const orderOfMagnitude = Math.pow(10, Math.floor(Math.log10(step))); // Find the magnitude (e.g., 10, 100, 1000)
  
  // Step 3: Round the step to the nearest multiple of the order of magnitude
  const roundedStep = Math.round(step / orderOfMagnitude) * orderOfMagnitude;

  // Step 4: Start from a value a bit lower than the min, ensuring we have one value below min
  const startValue = Math.floor(min / roundedStep) * roundedStep - roundedStep;

  // Step 5: End at a value a bit higher than the max, ensuring we have one value above max
  const endValue = Math.ceil(max / roundedStep) * roundedStep + roundedStep;

  // Step 6: Generate the sequence with the dynamically adjusted start and end
  const sequence = Array.from({ length: numElements }, (_, i) => startValue + i * roundedStep);

  return sequence;
}

[[100,200],
[23166,67123],
[25000,76500]].forEach(([min,max]) => console.log(generateSequence(min, max)))

I want to get only one value above the max value and one value less than the min value, if you see the result it’s giving me 220 & 240. Ideally with 220 the array should end, but then I need 9 integers which will get reduced to 8, so I want to shift my first integer to some more lower value and based on that sequence should get generated.

I need some rounded values if you check this kind of cases

const min = 23166;
const max = 67123;

I should get a clean integer value like 16000, 23000,

2

Answers


  1. Details are commented in example.

    // For demo purposes (formats console logs)
    const log = data => console.log(JSON.stringify(data));
    
    // Simple generator to count recursions
    function* counter(stop) {
      let index = 0;
      while (index < stop) {
        yield index++;
      }
    }
    
    let gen = counter(3);
    
    /**
     * Given a minimum number (@param min), a maximum number
     * (@param max), and an amount (@param size), calculate an 
     * array of numbers with a range of a lower number than min and
     * a higher number than max at an interval of a number
     * divisible by 10.
     * @param {number} min  - The lowest integer
     * @param {number} max  - The highest integer
     * @param {number} size - The amount of integers
     * @param {number} mod  - A counter that adjusts the size
     * @default is 0          recursively when the result maximum
     *                        is equal or less than max.
     * @return {Array}
     */
    const steps = (min, max, size, mod = 0) => {
      log(mod);
      // mod will recursively decrement by 1
      let den = mod + size;
      // V adjusts step size to roughly 10s, 100s, ect
      let V = (max - min) * 0.1;
      // Raw step size
      let step = (max - min) / den;
      // Adjusts step size to roughly 10s, 100s, ect
      step = (Math.ceil(step / V) * V);
      // Modify step to be divisible by 10
      step = Math.floor(step / 10) * 10;
      log("Step: " + step);
      // Ensure that the first number isn't too low
      min = min < step * 5 ? min : (min - step);
      // Process the numbers into an array of the desired pattern 
      let result = [...Array(size)].map((_, i) => min + (i * step));
      log(result);
      /*
        If the last number is equal to or less than the max, 
        the function will recursively process the array passing
        the @param mod decremented by 1.
      */
      if (result[size - 1] <= max) {
        // Yield --1 from generator
        mod = gen.next().value * -1;
        // Limit recursion
        if (mod < -3) {
          return result;
        }
        return steps(min, max, size, mod);
      }
      return result;
    }
    
    log(steps(100, 200, 9));
    log(steps(500, 1000, 9));
    Login or Signup to reply.
  2. Your code logic is far from generating an array that meets the conditions specified in your question. The code below will generate the expected array.

    function generateSequence(min, max, numElements = 9) {
      
      // Calculate step size for the sequence
      let step = (max - min) / (numElements - 3); 
      
      // Adjust step size for better spacing
      const roundedStep = step + (step / (numElements - 4));
      
      // Determine starting value below min
      const startValue = min - roundedStep;
    
      // Generate the sequence of rounded values
      const sequence = Array.from({ length: numElements - 1 }, (_, i) => 
        Math.round(startValue + i * roundedStep)
      );
    
      return sequence; 
    }
    
    [[100,200],
     [23166,67123],
     [25000,76500]].forEach(([min,max]) => 
       console.log(generateSequence(min, max))
    );
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search