random-elements
Advanced tools
Comparing version 0.1.3 to 0.2.0
export declare const pickRandomIndex: (arr: any[]) => number; | ||
/** Pseudo-random pick an alement of an array, retaining the element types. */ | ||
export declare const pickRandomElement: <T>(arr: T[]) => T; | ||
/** Pick exactly `count` elements from an array. | ||
* The same element will never appear more than once in the result, but | ||
* 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[]; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.pickRandomElement = exports.pickRandomIndex = void 0; | ||
exports.pickMultiple = exports.pickRandomElement = exports.pickRandomIndex = void 0; | ||
const pickRandomIndex = (arr) => Math.floor(Math.random() * arr.length); | ||
exports.pickRandomIndex = pickRandomIndex; | ||
/** Pseudo-random pick an alement of an array, retaining the element types. */ | ||
const pickRandomElement = (arr) => { | ||
@@ -10,1 +11,26 @@ return arr[(0, exports.pickRandomIndex)(arr)]; | ||
exports.pickRandomElement = pickRandomElement; | ||
/** Pick exactly `count` elements from an array. | ||
* The same element will never appear more than once in the result, but | ||
* 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) => { | ||
if (count < 1 || count > arr.length) { | ||
throw Error(`count is out of range: you provided ${count} which is not in the range [1;${arr.length}]`); | ||
} | ||
const shuffled = shuffleDurstenfeld(arr); | ||
let result = []; | ||
for (let i = 0; i < count; i++) { | ||
result.push(shuffled[i]); | ||
} | ||
return result; | ||
}; | ||
exports.pickMultiple = pickMultiple; | ||
/** Shuffles the given array without modifying the original array, i.e. returns a copy. */ | ||
const shuffleDurstenfeld = (array) => { | ||
let result = [...array]; // take copy | ||
for (let i = result.length - 1; i > 0; i--) { | ||
const j = Math.floor(Math.random() * (i + 1)); | ||
[result[i], result[j]] = [result[j], result[i]]; | ||
} | ||
return result; | ||
}; |
@@ -88,1 +88,37 @@ "use strict"; | ||
}); | ||
describe("Pick any number of unique elements", () => { | ||
const inputArray = ["one", "two", "three", "four", "five", "six", "seven"]; | ||
test("pick 2", () => { | ||
const elements = (0, _1.pickMultiple)(inputArray, 2); | ||
expect(elements.length).toBe(2); | ||
}); | ||
test("each element should exist in the original array", () => { | ||
const elements = (0, _1.pickMultiple)(inputArray, inputArray.length); | ||
for (const e of elements) { | ||
expect(inputArray).toContain(e); | ||
} | ||
}); | ||
test("invalid count values should throw Error", () => { | ||
expect(() => { | ||
(0, _1.pickMultiple)(inputArray, 0); | ||
}).toThrow("out of range"); | ||
expect(() => { | ||
(0, _1.pickMultiple)(inputArray, 10); | ||
}).toThrow("out of range"); | ||
}); | ||
test("the same element should never appear more than once", () => { | ||
for (let i = 0; i < REPETITIONS; i++) { | ||
const count = Math.floor(1 + Math.random() * inputArray.length); | ||
// console.log({ count }); | ||
const elements = (0, _1.pickMultiple)(inputArray, count); | ||
const onlyOnes = elements.filter((e) => e == "one"); | ||
expect(Array.isArray(onlyOnes)).toBeTruthy(); | ||
if (onlyOnes.length > 0) { | ||
expect(onlyOnes.length).toBe(1); | ||
} | ||
else { | ||
expect(onlyOnes.length).toBe(0); | ||
} | ||
} | ||
}); | ||
}); |
/** @type {import('ts-jest').JestConfigWithTsJest} */ | ||
module.exports = { | ||
preset: 'ts-jest', | ||
testEnvironment: 'node', | ||
}; | ||
preset: "ts-jest", | ||
testEnvironment: "node", | ||
verbose: true, | ||
modulePathIgnorePatterns: ["<rootDir>/dist/"], | ||
}; |
{ | ||
"name": "random-elements", | ||
"version": "0.1.3", | ||
"version": "0.2.0", | ||
"description": "Utility for picking one or more elements from any array", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
# Random Element picker | ||
For now, just provides a nicely-typed, well-tested utility for picking a random element from an array. | ||
Provides a nicely-typed, well-tested utility for picking one or multiple random element(s) from an array. | ||
## Coming soon: | ||
Pretty simple. | ||
- Pick any number of elements from an array, guarranteed to be unique | ||
The main benefits of this over doing it yourself: | ||
- Proper TypeScript generics ensure that the type of element array you submit is returned with the same types. Makes the compiler happy when you use this library in your own code. | ||
- Well tested, so prevents silly range errors and unexpected results. |
@@ -1,2 +0,2 @@ | ||
import { pickRandomElement, pickRandomIndex } from "."; | ||
import { pickMultiple, pickRandomElement, pickRandomIndex } from "."; | ||
@@ -89,1 +89,37 @@ const REPETITIONS = 1000; | ||
}); | ||
describe("Pick any number of unique elements", () => { | ||
const inputArray = ["one", "two", "three", "four", "five", "six", "seven"]; | ||
test("pick 2", () => { | ||
const elements = pickMultiple(inputArray, 2); | ||
expect(elements.length).toBe(2); | ||
}); | ||
test("each element should exist in the original array", () => { | ||
const elements = pickMultiple(inputArray, inputArray.length); | ||
for (const e of elements) { | ||
expect(inputArray).toContain(e); | ||
} | ||
}); | ||
test("invalid count values should throw Error", () => { | ||
expect(() => { | ||
pickMultiple(inputArray, 0); | ||
}).toThrow("out of range"); | ||
expect(() => { | ||
pickMultiple(inputArray, 10); | ||
}).toThrow("out of range"); | ||
}); | ||
test("the same element should never appear more than once", () => { | ||
for (let i = 0; i < REPETITIONS; i++) { | ||
const count = Math.floor(1 + Math.random() * inputArray.length); | ||
// console.log({ count }); | ||
const elements = pickMultiple(inputArray, count); | ||
const onlyOnes = elements.filter((e) => e == "one"); | ||
expect(Array.isArray(onlyOnes)).toBeTruthy(); | ||
if (onlyOnes.length > 0) { | ||
expect(onlyOnes.length).toBe(1); | ||
} else { | ||
expect(onlyOnes.length).toBe(0); | ||
} | ||
} | ||
}); | ||
}); |
export const pickRandomIndex = (arr: any[]): number => | ||
Math.floor(Math.random() * arr.length); | ||
/** Pseudo-random pick an alement of an array, retaining the element types. */ | ||
export const pickRandomElement = <T>(arr: T[]): T => { | ||
return arr[pickRandomIndex(arr)]; | ||
}; | ||
/** Pick exactly `count` elements from an array. | ||
* The same element will never appear more than once in the result, but | ||
* 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[] => { | ||
if (count < 1 || count > arr.length) { | ||
throw Error( | ||
`count is out of range: you provided ${count} which is not in the range [1;${arr.length}]` | ||
); | ||
} | ||
const shuffled = shuffleDurstenfeld(arr); | ||
let result = []; | ||
for (let i = 0; i < count; i++) { | ||
result.push(shuffled[i]); | ||
} | ||
return result; | ||
}; | ||
/** Shuffles the given array without modifying the original array, i.e. returns a copy. */ | ||
const shuffleDurstenfeld = <T>(array: T[]): T[] => { | ||
let result = [...array]; // take copy | ||
for (let i = result.length - 1; i > 0; i--) { | ||
const j = Math.floor(Math.random() * (i + 1)); | ||
[result[i], result[j]] = [result[j], result[i]]; | ||
} | ||
return result; | ||
}; |
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
24772
423
11