random-js icon indicating copy to clipboard operation
random-js copied to clipboard

Force value to either min or max

Open GreenImp opened this issue 4 years ago • 3 comments

I know this might be an odd question for a random library but, is there any way of forcing an engine to return the min or max value when using integer or real?

e.g.:

// force this to always return the min, 1
integer(1, 4);

// force this to always return the max, 4
integer(1, 4);

I've looked at creating a custom engine, and if the next() method returns 0 it seems to always return the min value:

const engine = {
  next() {
    return 0;
  },
};

integer(1, 4); // returns 1
integer(1, 4); // returns 1
integer(1, 4); // returns 1

I'm assuming it works by returning the number from the range, by index of the response from next(). But I can't find a way of forcing the max value.

GreenImp avatar Jul 21 '20 16:07 GreenImp

I know this is an odd request, so it's unlikely anyone else wants to achieve this but, just in case, this was my solution;

Min engine

Always returns the lowest possible value.

/**
 * Engine that always returns the minimum value.
 *
 * @type {{next(): number}}
 */
const minEngine = {
  /**
   * Returns the minimum number index, `0`
   *
   * @returns {number}
   */
  next() {
    return 0;
  },
};

E.g.

const random = new Random(minEngine);

random.integer(1, 4); // returns 1
random.integer(10, 300); // returns 10
random.integer(-55, -12); // returns -55

Max engine

Always returns the maximum value.

/**
 * Engine that always returns the maximum value.
 *
 * @type {{next(): number, range: number[]}}
 */
const maxEngine = {
  /**
   * The min / max number range (e.g. `[1, 10]`).
   *
   * This _must_ be set for the `next()` method to return the correct last index.
   *
   * @example
   * maxEngine.range = [1, 10];
   *
   * @type {number[]}
   */
  range: [],
  /**
   * Returns the maximum number index for the range
   *
   * @returns {number}
   */
  next() {
    // calculate the index of the max number
    return this.range[1] - this.range[0];
  },
};

The max and minimum values must be set against the maxEngine.range before use.

const random = new Random(maxEngine);

maxEngine.range = [1, 4];
random.integer(1, 4); // returns 4

maxEngine.range = [10, 300];
random.integer(10, 300); // returns 300

maxEngine.range = [-55, -12];
random.integer(-55, -12); // returns -12

It might seem a bit pointless, if I'm having to provide the min and max range, but I'm using it where I'm providing the data programatically, where I don't know what the values are in advance.

I'm not sure if this works with .real() but I only needed it to work for .integer().

I would be interested to know if there's a better way of achieving this (e.g. if random-js can provide the max index so I don't need to calculate it, or just the min/max values so they don't need to be specified manually).

GreenImp avatar Sep 07 '20 17:09 GreenImp

It would probably make more sense to make a max/min function that hooks into the random.integer/random.die/random.real and takes the entire call as an argument @ckknight would this be a possibility for v3.0.0?

rawr51919 avatar Sep 16 '23 14:09 rawr51919

Added in PR #65, will be fixed as soon as it's finished

rawr51919 avatar Sep 21 '23 04:09 rawr51919