random-elements
Advanced tools
Comparing version 0.2.0 to 0.3.0
export declare const pickRandomIndex: (arr: any[]) => number; | ||
/** Pick `count` indexes out of a sequence of indexes which counts from 0..`size` */ | ||
export declare const pickRandomIndexes: (size: number, count: number) => number[]; | ||
/** Pseudo-random pick an alement of an array, retaining the element types. */ | ||
@@ -7,3 +9,6 @@ export declare const pickRandomElement: <T>(arr: T[]) => T; | ||
* since we do not check for equality, if the original array contains | ||
* duplicates then these values may well occur multiple times in the result. */ | ||
export declare const pickMultiple: <T>(arr: T[], count: number) => T[]; | ||
* duplicates then these values may well occur multiple times in the result. | ||
* | ||
* The given array will NOT be modified. | ||
* */ | ||
export declare const pickMultipleRandomElements: <T>(arr: T[], count: number) => T[]; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.pickMultiple = exports.pickRandomElement = exports.pickRandomIndex = void 0; | ||
exports.pickMultipleRandomElements = exports.pickRandomElement = exports.pickRandomIndexes = exports.pickRandomIndex = void 0; | ||
const pickRandomIndex = (arr) => Math.floor(Math.random() * arr.length); | ||
exports.pickRandomIndex = pickRandomIndex; | ||
/** Pick `count` indexes out of a sequence of indexes which counts from 0..`size` */ | ||
const pickRandomIndexes = (size, count) => { | ||
let arr = []; | ||
for (let i = 0; i < size; i++) { | ||
arr.push(i); | ||
} | ||
return (0, exports.pickMultipleRandomElements)(arr, count); | ||
}; | ||
exports.pickRandomIndexes = pickRandomIndexes; | ||
/** Pseudo-random pick an alement of an array, retaining the element types. */ | ||
@@ -14,4 +23,7 @@ const pickRandomElement = (arr) => { | ||
* since we do not check for equality, if the original array contains | ||
* duplicates then these values may well occur multiple times in the result. */ | ||
const pickMultiple = (arr, count) => { | ||
* duplicates then these values may well occur multiple times in the result. | ||
* | ||
* The given array will NOT be modified. | ||
* */ | ||
const pickMultipleRandomElements = (arr, count) => { | ||
if (count < 1 || count > arr.length) { | ||
@@ -27,3 +39,3 @@ throw Error(`count is out of range: you provided ${count} which is not in the range [1;${arr.length}]`); | ||
}; | ||
exports.pickMultiple = pickMultiple; | ||
exports.pickMultipleRandomElements = pickMultipleRandomElements; | ||
/** Shuffles the given array without modifying the original array, i.e. returns a copy. */ | ||
@@ -30,0 +42,0 @@ const shuffleDurstenfeld = (array) => { |
@@ -91,7 +91,7 @@ "use strict"; | ||
test("pick 2", () => { | ||
const elements = (0, _1.pickMultiple)(inputArray, 2); | ||
const elements = (0, _1.pickMultipleRandomElements)(inputArray, 2); | ||
expect(elements.length).toBe(2); | ||
}); | ||
test("each element should exist in the original array", () => { | ||
const elements = (0, _1.pickMultiple)(inputArray, inputArray.length); | ||
const elements = (0, _1.pickMultipleRandomElements)(inputArray, inputArray.length); | ||
for (const e of elements) { | ||
@@ -103,6 +103,6 @@ expect(inputArray).toContain(e); | ||
expect(() => { | ||
(0, _1.pickMultiple)(inputArray, 0); | ||
(0, _1.pickMultipleRandomElements)(inputArray, 0); | ||
}).toThrow("out of range"); | ||
expect(() => { | ||
(0, _1.pickMultiple)(inputArray, 10); | ||
(0, _1.pickMultipleRandomElements)(inputArray, 10); | ||
}).toThrow("out of range"); | ||
@@ -114,3 +114,3 @@ }); | ||
// console.log({ count }); | ||
const elements = (0, _1.pickMultiple)(inputArray, count); | ||
const elements = (0, _1.pickMultipleRandomElements)(inputArray, count); | ||
const onlyOnes = elements.filter((e) => e == "one"); | ||
@@ -127,1 +127,42 @@ expect(Array.isArray(onlyOnes)).toBeTruthy(); | ||
}); | ||
describe("Convenient index-picking utilities", () => { | ||
test("all indexes from result should be unique", () => { | ||
const indexesPicked = (0, _1.pickRandomIndexes)(3, 3); | ||
expect(indexesPicked).toHaveLength(3); | ||
expect(indexesPicked.filter((x) => x === 0)).toHaveLength(1); | ||
expect(indexesPicked.filter((x) => x === 1)).toHaveLength(1); | ||
expect(indexesPicked.filter((x) => x === 2)).toHaveLength(1); | ||
}); | ||
test("all indexes from result should be in range", () => { | ||
for (let i = 0; i < REPETITIONS; i++) { | ||
const indexesPicked = (0, _1.pickRandomIndexes)(10, 5); // 50% | ||
expect(indexesPicked.every((x) => x >= 0 && x < 10)).toBeTruthy(); | ||
} | ||
}); | ||
test("all possible combinations/orders should appear", () => { | ||
let combinations = []; | ||
for (let i = 0; i < REPETITIONS; i++) { | ||
const indexesPicked = (0, _1.pickRandomIndexes)(3, 3); | ||
combinations.push(indexesPicked); | ||
} | ||
expect(combinations).toHaveLength(REPETITIONS); | ||
const possible = ["012", "021", "201", "210", "120", "102"]; | ||
let found = new Set(); | ||
for (const c of combinations) { | ||
const pattern = c.join(""); | ||
expect(possible.find((x) => x === pattern)).toBeDefined(); // no impossible combinations | ||
found.add(pattern); | ||
} | ||
expect(found.size).toBe(6); | ||
}); | ||
test("specifying count larger than size throws error", () => { | ||
expect(() => { | ||
(0, _1.pickRandomIndexes)(3, 4); | ||
}).toThrow("out of range"); | ||
}); | ||
test("specifying size zero throws error", () => { | ||
expect(() => { | ||
(0, _1.pickRandomIndexes)(0, 0); | ||
}).toThrow(); | ||
}); | ||
}); |
{ | ||
"name": "random-elements", | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"description": "Utility for picking one or more elements from any array", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
@@ -11,1 +11,8 @@ # Random Element picker | ||
- Well tested, so prevents silly range errors and unexpected results. | ||
Useful functions: | ||
- pickRandomIndex | ||
- pickRandomIndexes | ||
- pickRandomElement (type safe arrays! no mutation!) | ||
- pickMultipleRandomElements (same as above, but returns multiple elements) |
@@ -1,2 +0,7 @@ | ||
import { pickMultiple, pickRandomElement, pickRandomIndex } from "."; | ||
import { | ||
pickMultipleRandomElements, | ||
pickRandomElement, | ||
pickRandomIndex, | ||
pickRandomIndexes, | ||
} from "."; | ||
@@ -93,7 +98,7 @@ const REPETITIONS = 1000; | ||
test("pick 2", () => { | ||
const elements = pickMultiple(inputArray, 2); | ||
const elements = pickMultipleRandomElements(inputArray, 2); | ||
expect(elements.length).toBe(2); | ||
}); | ||
test("each element should exist in the original array", () => { | ||
const elements = pickMultiple(inputArray, inputArray.length); | ||
const elements = pickMultipleRandomElements(inputArray, inputArray.length); | ||
for (const e of elements) { | ||
@@ -105,6 +110,6 @@ expect(inputArray).toContain(e); | ||
expect(() => { | ||
pickMultiple(inputArray, 0); | ||
pickMultipleRandomElements(inputArray, 0); | ||
}).toThrow("out of range"); | ||
expect(() => { | ||
pickMultiple(inputArray, 10); | ||
pickMultipleRandomElements(inputArray, 10); | ||
}).toThrow("out of range"); | ||
@@ -116,3 +121,3 @@ }); | ||
// console.log({ count }); | ||
const elements = pickMultiple(inputArray, count); | ||
const elements = pickMultipleRandomElements(inputArray, count); | ||
const onlyOnes = elements.filter((e) => e == "one"); | ||
@@ -128,1 +133,49 @@ expect(Array.isArray(onlyOnes)).toBeTruthy(); | ||
}); | ||
describe("Convenient index-picking utilities", () => { | ||
test("all indexes from result should be unique", () => { | ||
const indexesPicked = pickRandomIndexes(3, 3); | ||
expect(indexesPicked).toHaveLength(3); | ||
expect(indexesPicked.filter((x) => x === 0)).toHaveLength(1); | ||
expect(indexesPicked.filter((x) => x === 1)).toHaveLength(1); | ||
expect(indexesPicked.filter((x) => x === 2)).toHaveLength(1); | ||
}); | ||
test("all indexes from result should be in range", () => { | ||
for (let i = 0; i < REPETITIONS; i++) { | ||
const indexesPicked = pickRandomIndexes(10, 5); // 50% | ||
expect(indexesPicked.every((x) => x >= 0 && x < 10)).toBeTruthy(); | ||
} | ||
}); | ||
test("all possible combinations/orders should appear", () => { | ||
let combinations = []; | ||
for (let i = 0; i < REPETITIONS; i++) { | ||
const indexesPicked = pickRandomIndexes(3, 3); | ||
combinations.push(indexesPicked); | ||
} | ||
expect(combinations).toHaveLength(REPETITIONS); | ||
const possible = ["012", "021", "201", "210", "120", "102"]; | ||
let found = new Set(); | ||
for (const c of combinations) { | ||
const pattern = c.join(""); | ||
expect(possible.find((x) => x === pattern)).toBeDefined(); // no impossible combinations | ||
found.add(pattern); | ||
} | ||
expect(found.size).toBe(6); | ||
}); | ||
test("specifying count larger than size throws error", () => { | ||
expect(() => { | ||
pickRandomIndexes(3, 4); | ||
}).toThrow("out of range"); | ||
}); | ||
test("specifying size zero throws error", () => { | ||
expect(() => { | ||
pickRandomIndexes(0, 0); | ||
}).toThrow(); | ||
}); | ||
}); |
export const pickRandomIndex = (arr: any[]): number => | ||
Math.floor(Math.random() * arr.length); | ||
/** Pick `count` indexes out of a sequence of indexes which counts from 0..`size` */ | ||
export const pickRandomIndexes = (size: number, count: number) => { | ||
let arr = []; | ||
for (let i = 0; i < size; i++) { | ||
arr.push(i); | ||
} | ||
return pickMultipleRandomElements(arr, count); | ||
}; | ||
/** Pseudo-random pick an alement of an array, retaining the element types. */ | ||
@@ -12,4 +21,7 @@ export const pickRandomElement = <T>(arr: T[]): T => { | ||
* since we do not check for equality, if the original array contains | ||
* duplicates then these values may well occur multiple times in the result. */ | ||
export const pickMultiple = <T>(arr: T[], count: number): T[] => { | ||
* duplicates then these values may well occur multiple times in the result. | ||
* | ||
* The given array will NOT be modified. | ||
* */ | ||
export const pickMultipleRandomElements = <T>(arr: T[], count: number): T[] => { | ||
if (count < 1 || count > arr.length) { | ||
@@ -16,0 +28,0 @@ throw Error( |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
29487
538
18