Generate random numbers that are consecutively unique
npx @tessl/cli install tessl/npm-unique-random@4.0.0Unique Random generates random numbers that are consecutively unique. It provides two distinct algorithms: consecutive uniqueness (ensuring no two consecutive random numbers are the same) and exhaustive uniqueness (cycling through all possible values before repeating). Both functions return callable functions that are also iterable, making them versatile for different usage patterns.
npm install unique-randomimport { consecutiveUniqueRandom, exhaustiveUniqueRandom } from "unique-random";For CommonJS:
const { consecutiveUniqueRandom, exhaustiveUniqueRandom } = require("unique-random");import { consecutiveUniqueRandom } from "unique-random";
const random = consecutiveUniqueRandom(1, 10);
console.log(random(), random(), random());
//=> 5 2 6The returned function is also iterable:
import { exhaustiveUniqueRandom } from "unique-random";
const random = exhaustiveUniqueRandom(1, 10);
for (const number of random) {
console.log(number);
// The unique numbers will be iterated over infinitely
if (stopCondition) {
break;
}
}Generate random numbers that are consecutively unique, meaning that each number in the sequence is distinct from the one immediately before it.
/**
* Generate random numbers that are consecutively unique
* @param minimum - Lower bound of random range (inclusive)
* @param maximum - Upper bound of random range (inclusive)
* @returns A function that returns random numbers, also implements Symbol.iterator
*/
function consecutiveUniqueRandom(
minimum: number,
maximum: number
): (() => number) & {[Symbol.iterator](): Iterator<number>};Usage Examples:
import { consecutiveUniqueRandom } from "unique-random";
// Basic function calls
const random = consecutiveUniqueRandom(1, 5);
console.log(random()); // e.g., 3
console.log(random()); // e.g., 1 (never 3 again immediately)
console.log(random()); // e.g., 4 (never 1 again immediately)
// Iterator usage
const randomIterator = consecutiveUniqueRandom(1, 3);
for (const value of randomIterator) {
console.log(value); // Infinite sequence: 2, 1, 3, 2, 1, ...
if (someCondition) break;
}
// Manual iterator
const manualRandom = consecutiveUniqueRandom(1, 10);
const iterator = manualRandom[Symbol.iterator]();
console.log(iterator.next().value); // Random number 1-10
console.log(iterator.next().value); // Different from previousBehavior:
Generate random numbers that do not repeat until the entire range has appeared. This function cycles through all possible values before repeating any value.
/**
* Generate random numbers that do not repeat until the entire range has appeared
* @param minimum - Lower bound of random range (inclusive)
* @param maximum - Upper bound of random range (inclusive)
* @returns A function that returns random numbers, also implements Symbol.iterator
*/
function exhaustiveUniqueRandom(
minimum: number,
maximum: number
): (() => number) & {[Symbol.iterator](): Iterator<number>};Usage Examples:
import { exhaustiveUniqueRandom } from "unique-random";
// Exhaustive cycling through range
const random = exhaustiveUniqueRandom(1, 3);
console.log(random()); // e.g., 2
console.log(random()); // e.g., 1 (not 2)
console.log(random()); // e.g., 3 (not 2 or 1)
console.log(random()); // Now cycle resets, could be any of 1, 2, 3
// Iterator usage
const exhaustiveIterator = exhaustiveUniqueRandom(1, 4);
const values = [];
for (let i = 0; i < 8; i++) {
values.push(exhaustiveIterator().next ? exhaustiveIterator() : exhaustiveIterator());
}
// values contains all numbers 1-4 twice, but in random order within each cycle
// Fair distribution for games
const diceRoll = exhaustiveUniqueRandom(1, 6);
// Guarantees each number 1-6 appears once before any repeatsBehavior:
// Return type for both functions - callable and iterable
type UniqueRandomFunction = (() => number) & {
[Symbol.iterator](): Iterator<number>;
};
// Iterator interface
interface Iterator<T> {
next(): { value: T; done: boolean };
}minimum === maximum, both functions always return the same valueconsecutiveUniqueRandom(5, 5) and exhaustiveUniqueRandom(5, 5) both always return 5exhaustiveUniqueRandom keeps an array of unconsumed values proportional to range sizeconsecutiveUniqueRandomexhaustiveUniqueRandomexhaustiveUniqueRandom