maxxdev
maxxdev

Reputation: 313

Build JS arrays by key into one - find a best solution

What's the best solution to mapping 2 multiple arrays to build one by key? I have 1 array with users who have their profile data like

var users = [{id:5, name:'Alex'}, {id:17, name:'Tom'}, {id:11, name:'John'}];

Also I have another one array of cars with key user_id To determine which machine belongs to which user.

var cars = [{id:333, name:'Nissan', user_id:11}, {id:444, name:'Toyota', user_id:17}, {id:555, name:'BMW', user_id:999}];

So we can see that Tom have Toyota and John have Nissan.

So result should be a new array with mapped result

[{
"profile": {
    "id": 17,
    "name": "Tom"
},
"car": {
    "id": 444,
    "name": "Toyota",
    "user_id": 17
}
}, {
"profile": {
    "id": 11,
    "name": "John"
},
"car": {
    "id": 333,
    "name": "Nissan",
    "user_id": 11
}

}]

My solution is use forEach throw users and sub forEach throw cars and there compare user.id with car.user_id

https://jsfiddle.net/r7qwke1f/37/

Upvotes: 0

Views: 49

Answers (4)

koningdavid
koningdavid

Reputation: 8085

There are basically two methods you would want to use. You want to map the users to the cars, so you want to find a car for the user you are referring to

const result = users.map((user) => {
    const car = cars.find(car => car.user_id === user.id);
    return {
        profile: user,
        car,
    }
})

Upvotes: 0

Nenad Vracar
Nenad Vracar

Reputation: 122027

You can use reduce() and find() methods to get desired result.

var users = [{id:5, name:'Alex'}, {id:17, name:'Tom'}, {id:11, name:'John'}];
var cars = [{id:333, name:'Nissan', user_id:11}, {id:444, name:'Toyota', user_id:17}, {id:555, name:'BMW', user_id:999}];

var r = users.reduce(function(r, e) {
  var car = cars.find(a => a.user_id == e.id);
  if(car) r.push({profile: e, car: car});
  return r;
}, [])

console.log(r)

Upvotes: 0

Hobroker
Hobroker

Reputation: 380

Another solution

const mappedUsersCars = users.map((user) => ({
    profile: user,
    car: cars.filter((car) => car.user_id === user.id)[0]
}))

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386550

You could use a two loop approach instead of a nested loop approach by collecting first all users in a hash table anbd then iterate all cars and if a user is available, then create a new result set.

var users = [{ id: 5, name: 'Alex' }, { id: 17, name: 'Tom' }, { id: 11, name: 'John' }],
    cars = [{ id: 333, name: 'Nissan', user_id: 11 }, { id: 444, name: 'Toyota', user_id: 17 }, { id: 555, name: 'BMW', user_id: 999 }],
    hash = {},
    result = [];

users.forEach(function (user) {
    hash[user.id] = user;
});

cars.forEach(function (car) {
    if (hash[car.user_id]) {
        result.push({ profile: hash[car.user_id], car: car });
    }
});

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 2

Related Questions