user14849955
user14849955

Reputation:

Conjoin Related Objects Into One Object Array? (javascript)

I have some user and permission data that has been queried from my database. I would like the access object for each person to be conjoined with each user object so that when I map through the array in my app on a user permissions page, all the data is easily accessible.

Fortunately, my data that needs to be conjoined is in indexed order.

Question: How do I conjoin the access object with the user object based on Id.

My attempt:

const data = permissions.map((perm, pIndex) => {
  return users.map((user, uIndex) => {
    return pIndex === uIndex;
  });
});

My Data:

user = [{
    firstName: "steve",
    age: 22,
    _id: "789"
  },
  {
    fistName: "bill",
    age: 18,
    _id: "456"
  },
  {
    firstName: "jeff",
    age: 15,
    _id: "123"
  }
]

permissions = [{
    userId: "789",
    access: ["321", "654"]
  },
  {
    userId: "456",
    access: ["654"]
  },
  {
    userId: "123",
    access: ["321", "654", "987"]
  },
]

Desired output:

user = [{
    firstName: "steve",
    age: 22,
    _id: "789",
    access: ["321", "654"]
  },
  {
    fistName: "bill",
    age: 18,
    _id: "456",
    access: ["654"]
  },
  {
    firstName: "jeff",
    age: 15,
    _id: "123",
    access: ["321", "654", "987"]
  }
]

My current output has undefined values mixed in the array like:

[{obj}, undefined, undefined],
[undefined, {obj}, undefined],
[undefined, undefined, {obj}]

thanks!

Upvotes: 2

Views: 81

Answers (3)

Alen.Toma
Alen.Toma

Reputation: 4870

You Could simple use reduce, have a look below

var users = [{
    firstName: "steve",
    age: 22,
    _id: "789"
  },
  {
    fistName: "bill",
    age: 18,
    _id: "456"
  },
  {
    firstName: "jeff",
    age: 15,
    _id: "123"
  }
]

var permissions = [{
    userId: "789",
    access: ["321", "654"]
  },
  {
    userId: "456",
    access: ["654"]
  },
  {
    userId: "123",
    access: ["321", "654", "987"]
  },
]

var data = users.reduce((array, item) => {
  item.access = permissions.find((f) => f.userId == item._id).access;
  array.push(item)
  return array;
}, [])
console.log(data);

Upvotes: 0

Majed Badawi
Majed Badawi

Reputation: 28414

You can use .find to get the permission by userId:

const users = [
  { firstName: "steve", age: 22, _id: "789" },
  { fistName: "bill", age: 18, _id: "456" },
  { firstName: "jeff", age: 15, _id: "123" }
];

const permissions = [
  { userId: "789", access: ["321", "654"] },
  { userId: "456", access: ["654"] },
  { userId: "123", access: ["321", "654", "987"] },
];

const res = users.map(user => {
  const { access = [] } 
    = permissions.find(permission => permission.userId===user._id) || {};
  return {...user, access};
});

console.log(res);

Upvotes: 1

Ori Drori
Ori Drori

Reputation: 191976

Convert the permissions to a Map by id, and then map the users and take the access from the Map by the user's _id:

const fn = (users, permissions) => {
  // create a Map using the id as the key, and the rest of the object as value
  const permissionsMap = new Map(permissions.map(({ userId, ...rest }) => [userId, rest]))
  
  // combine the users with the relevant access from the Map
  return users.map(o => ({ ...o, ...permissionsMap.get(o._id) }))
}

const users = [{"firstName":"steve","age":22,"_id":"789"},{"fistName":"bill","age":18,"_id":"456"},{"firstName":"jeff","age":15,"_id":"123"}]
const permissions = [{"userId":"789","access":["321","654"]},{"userId":"456","access":["654"]},{"userId":"123","access":["321","654","987"]}]

const result = fn(users, permissions)

console.log(result)

Upvotes: 2

Related Questions