← Download MyJS
MyJS block
sample 1.0.0
Picks some items from an array at random, with no item picked twice. Every item is equally likely to be picked, and the picks come back in a random order.
- Exports
-
sample - Works in
- Browser and Node.js
- Requires
- random 1.x
- Tags
- random
The code of version 1.0.0
/**
* Picks some items from an array at random, with no item picked twice. Every
* item is equally likely to be picked, and the picks come back in a random
* order.
* @template T
* @param {ArrayLike.<T>|Iterable.<T>} arr
* The array, or array-like or iterable object (such as a string or a Set),
* to pick from.
* @param {number} count
* How many items to pick, from 0 up to the number of items in `arr`.
* @param {boolean} [useCrypto=false]
* If `true`, uses `crypto.getRandomValues()` instead of `Math.random()`, so
* the picks can't be predicted.
* @returns {Array.<T>}
* A new array of `count` items from `arr`. The original isn't changed.
* @throws {RangeError}
* If `count` isn't a whole number from 0 up to the number of items.
*
* @example <caption>Drawing lottery numbers</caption>
* const balls = Array.from({ length: 49 }, (_, i) => i + 1);
* sample(balls, 6);
* // → six different numbers, like [23, 7, 41, 2, 38, 15]
*
* @example <caption>Picking winners fairly</caption>
* sample(['Ana', 'Ben', 'Cy', 'Dee', 'Eve'], 2, true);
* // → two different names, like ['Dee', 'Ana']
*/
function sample(arr, count, useCrypto) {
const copy = Array.from(arr);
if (!Number.isInteger(count) || count < 0 || count > copy.length) {
throw new RangeError(`count must be a whole number from 0 to ${copy.length}.`);
}
// Shuffle only the first count places: each gets a random item from the
// ones not picked yet
for (let i = 0; i < count; i++) {
const j = random(i, copy.length, { useCrypto, returnInt: true });
[copy[i], copy[j]] = [copy[j], copy[i]];
}
copy.length = count;
return copy;
}
Versions
-
1.0.0 Oct 23, 2026
Initial