faker-js / faker

Generate massive amounts of fake data in the browser and node.js
https://fakerjs.dev
Other
12.99k stars 919 forks source link

Add method/option to pick elements from an array multiple times #3222

Open ST-DDT opened 3 weeks ago

ST-DDT commented 3 weeks ago

Clear and concise description of the problem

The current arrayElements method only takes elements from an array once. The multiple method only uses a function as input.

I need a method to pick random elements from an array multiple times.

Suggested solution

Either as an additional parameter for the existing arrayElements repeatedElements: boolean = false or a new method (not sure what to call it)


Here a pseudo implementations with some potential performance improvements (safes a few invocations to faker.number.int by stacking them):

function multipleArrayElements(values: T[], count: numberOrRange) {

  const valuesLength = values.length:
  const divisions = Math.floor(Math.log(Number.MAX_SAFE_INTEGER) / Math.log(valuesLength));
  const base = valuesLength ** divisions;
  const repeats = Math.floor(count / divisions);
  const remains = count % divisions

  const result = [];
  for(let i = 0; i<repeats; i++) {
    let random = faker.number.int(base);
    for (let j=0; j<divisions; j++) {
      const index = random % valuesLength;
      random /= valuesLength;
      result.push(values[index]);
    }
  }
  let random = faker.number.int(base);
  for (let j=0; j<remains; j++) {
    const index = random % valuesLength;
    random /= valuesLength;
    result.push(values[index]);
  }
  return result;
}

The performance part needs actual benchmarks though.

Alternative

Keep using the existing code.

Additional context

This method can be used to improve the performance of the string module and similar modules.

And also reduce code duplication a bit, namely code like this:

https://github.com/faker-js/faker/blob/af1dbcdbf363a12c448834dff031a698c8925e2e/src/modules/string/index.ts#L148-L151

Due to "improvements" you would need to call faker.number.int() only once per 11 random elements of 26 characters.

github-actions[bot] commented 3 weeks ago

Thank you for your feature proposal.

We marked it as "waiting for user interest" for now to gather some feedback from our community: