Generate an array with random data without using a for loop
Asked Answered
A

5

16

I am using the faker.js library to generate random data and I have a couple of factory functions that generate a series of user data:

const createUser = () => {
  return {
    name: faker.name.findName(),
    email: faker.internet.email(),
    address: faker.address.streetAddress(),
    bio: faker.lorem.sentence(),
    image: faker.image.avatar(),
  };
};

const createUsers = (numUsers = 5) => {
  return Array(numUsers).fill(createUser());
};

let fakeUsers = createUsers(5);
console.log(fakeUsers);

The problem with this Array.fill approach is that it returns the same data n number of times. I want 5 different users to be returned from my factory.

How do I do this?

Adulteress answered 17/3, 2017 at 15:42 Comment(3)
Why do you not want to use a loop?Cellini
no reason - just want to know alternate ways of doing things with Array.fillAdulteress
Set aside the Array functors there are tons of other ways to loop in JS. You may even do this job recursively.Undertaking
S
33

Array.from allows you to create an array and initialize it with values returned from a callback function in one step:

const createUsers = (numUsers = 5) => {
    return Array.from({length: numUsers}, createUser);
}
Sear answered 17/3, 2017 at 16:54 Comment(1)
No empty fills, no maps, just exactly what should be done. Thanks!Frodeen
C
7

Create an array with blanks, and then use .map() to create users:

const createUsers = (numUsers = 5) => {
    return Array(numUsers)
        .fill(null)
        .map(createUser);
}
Cloudburst answered 17/3, 2017 at 15:47 Comment(0)
F
5

You can now do this with the multiple helper much more easily as of the latest version (v8.0.0):

const createUser = () => {
  return {
    name: faker.person.fullName(),
    email: faker.internet.email(),
    address: faker.location.streetAddress(),
    bio: faker.lorem.sentence(),
    image: faker.image.avatar(),
  };
};

faker.helpers.multiple(createUser, { count: 5 })

See the docs for more info: https://fakerjs.dev/api/helpers.html#multiple

Flighty answered 16/5, 2023 at 17:58 Comment(1)
name and address are deprecated, use person and location respectively.. instead of name.findName() use person.fullName() instead of address.streetAddress() use location.streetAddress()Readymix
P
4

Creating an array via the Array constructor will yield an non mappable (or iterable for that matter) array.

This happens because the constructor will give you an array with X uninitialized values, causing map to fail. Using fill to initialize the values, even if initialized to null or undefined, will work:

const createUser = () => {
  return {
    name: faker.name.findName(),
    email: faker.internet.email(),
    address: faker.address.streetAddress(),
    bio: faker.lorem.sentence(),
    image: faker.image.avatar()
  }
}

const createUsers = (numUsers = 5) => {
  return new Array(numUsers)
    .fill(undefined)
    .map(createUser);
}

let fakeUsers = createUsers(5)
console.log(fakeUsers)

https://jsbin.com/punesorico/edit?html,js,console

Protection answered 17/3, 2017 at 15:57 Comment(1)
nice explanationAdulteress
U
1

Here is another way of doing this job by a TCO recursive function;

function getFakeObject(){
  return Array(5).fill()
                 .reduce(o => Object.assign(o,{[String.fromCharCode(...Array(5).fill().map(_ => ~~(Math.random()*26)+65))] : String.fromCharCode(...Array(5).fill().map(_ => ~~(Math.random()*26)+97))}),{});
}

function makeFakeObjectsArray(n, r = []){
 return n ? makeFakeObjectsArray(n-1,(r.push(getFakeObject()),r)) : r;
}

console.log(makeFakeObjectsArray(5));
Undertaking answered 17/3, 2017 at 16:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.