Skip to content

Commit 2b84b33

Browse files
authored
fix(helpers): uniform distribution in helpers.arrayElements (#1770)
1 parent 3a44d5f commit 2b84b33

3 files changed

Lines changed: 46 additions & 6 deletions

File tree

src/modules/helpers/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -594,8 +594,9 @@ export class HelpersModule {
594594
let temp: T;
595595
let index: number;
596596

597+
// Shuffle the last `count` elements of the array
597598
while (i-- > min) {
598-
index = Math.floor((i + 1) * this.faker.number.float({ max: 0.99 }));
599+
index = this.faker.number.int(i);
599600
temp = arrayCopy[index];
600601
arrayCopy[index] = arrayCopy[i];
601602
arrayCopy[i] = temp;

test/__snapshots__/helpers.spec.ts.snap

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -195,15 +195,15 @@ exports[`helpers > 1211 > arrayElements > noArgs 1`] = `
195195

196196
exports[`helpers > 1211 > arrayElements > with array 1`] = `
197197
[
198-
"r",
198+
"d",
199199
"o",
200-
"l",
200+
"r",
201201
"!",
202202
"l",
203-
"d",
204-
"W",
205203
"H",
204+
"W",
206205
"e",
206+
"l",
207207
"o",
208208
"l",
209209
" ",
@@ -213,7 +213,7 @@ exports[`helpers > 1211 > arrayElements > with array 1`] = `
213213
exports[`helpers > 1211 > arrayElements > with array and count 1`] = `
214214
[
215215
"r",
216-
"o",
216+
" ",
217217
"!",
218218
]
219219
`;

test/helpers.spec.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,45 @@ describe('helpers', () => {
292292

293293
expect(result).toHaveLength(0);
294294
});
295+
296+
it('should return the only element in the array when there is only 1', () => {
297+
const testArray = ['hello'];
298+
const actual = faker.helpers.arrayElements(testArray);
299+
expect(actual).toEqual(testArray);
300+
});
301+
302+
it('should return each element with a somewhat equal distribution with 2 elements', () => {
303+
const input = Array.from({ length: 2 }, (_, i) => i);
304+
const occurrences = Array.from({ length: 2 }, () => 0);
305+
306+
for (let i = 0; i < 1000; i++) {
307+
const [result] = faker.helpers.arrayElements(input, 1);
308+
occurrences[result]++;
309+
}
310+
311+
for (const occurrence of occurrences) {
312+
expect(occurrence).toBeGreaterThanOrEqual(400);
313+
expect(occurrence).toBeLessThanOrEqual(600);
314+
}
315+
});
316+
317+
it.each([10, 100, 1000])(
318+
'should return each element with a somewhat equal distribution with %s elements',
319+
(length) => {
320+
const input = Array.from({ length }, (_, i) => i % 10);
321+
const occurrences = Array.from({ length: 10 }, () => 0);
322+
323+
for (let i = 0; i < 1000; i++) {
324+
const [result] = faker.helpers.arrayElements(input, 1);
325+
occurrences[result]++;
326+
}
327+
328+
for (const occurrence of occurrences) {
329+
expect(occurrence).toBeGreaterThanOrEqual(70);
330+
expect(occurrence).toBeLessThanOrEqual(130);
331+
}
332+
}
333+
);
295334
});
296335

297336
describe('slugify()', () => {

0 commit comments

Comments
 (0)