在javascript中将三个数组中的对象合并为一个对象的快速且基于性能的方法

zlhcx6iw  于 2023-01-08  发布在  Java
关注(0)|答案(3)|浏览(289)

我有一个对象数组,它在JavaScript中有一些属性,基本结构如下:

{
  id: 123-456
  username: sdfjweihg
}

然后我有三个很大的数组,都是未排序的,都是对象数组,但是对象都有各种不同的匹配字段,但是它们都有一个acccount_id,匹配上面对象的id
上面的对象也以数组的形式出现,所以我做了如下操作:

let fullUsers = [];
for(let i = 0; i < users.length; i++) {
   fullUser.push({
      user: users[i],
      favorite_movie: moviesOfusers.filter((movie) => movie.account_id === users[i].id),
      favorite_toys: toysOfusers.filter((toy) => toy.account_id === users[i].id),
      favorite_colors: colorsOfUsers.filter((color) => color.account_id === users[i].id)
   )};
}

其中moviesOfuserstoysOfUserscolorsOfUsers是数组,它们有各种各样的其他属性,但匹配account_id。它工作正常,做我想要的,但我需要一些CPU密集度更低和更快的东西。如果有人有任何建议,以实现相同的搜索和附加,这是更好的,我喜欢一些新的想法。谢谢!

fzwojiic

fzwojiic1#

你能做的最好的事情就是在一次迭代中把每个大数组都简化成一个Map...

const colorsByAccountId = colorsOfUsers.reduce((acc,color) => {
   const { account_id } = color
   if(acc[account_id]) {
     acc[account_id].push(color)
   } else {
     acc[account_id] = [color]
   }
   return acc
},{})

然后。

const fullUsers = users.map((user) => ({
   user,
   colors: colorsByAccountId[user.id] || [],
   ...other stuff
})

不知道这是否能给你带来足够的好处。

6jjcrrmo

6jjcrrmo2#

您可以预先计算电影、玩具和汽车的帐户ID的簿记数组:

const userToMovie = {}
const userToToy = {}
const userToColor = {}
moviesOfusers.forEach(movie => { userToMovie[movie.account_id] = movie })
toysOfusers.forEach(toy => { userToToy[toy.account_id] = toy })
colorsOfUsers.forEach(color => { userToColor[color.account_id = color })

let fullUsers = [];
for(let i = 0; i < users.length; i++) {
   fullUsers.push({
      user: users[i],
      favorite_movie: userToMovie[users[i].id],
      favorite_toys: userToToy[users[i].id],
      favorite_colors: userToColor[users[i].id]
   )};
}
db2dz4w8

db2dz4w83#

就我个人而言,我只会将用户Map到一个键控集,然后使用它来循环其他项。

  • 对用户循环一次(reduce)
  • 每个数据集循环一次(forEach X每个数据集)
  • 您只需查看对象的值一次。(Object.keys)
/* Data */

const users = [
  {id: 1, name: 'Bob'}, 
  { id: 2, name: 'Al' }
];

const toys = [
  { id:1, name: 'foo'},
  { id:1, name: 'bar'},
  { id:2, name: 'baz'}
];

const books = [
  {id: 1, name: 'book1'}
]

/* First step, make the easy loop up by id for the users */
const mappedById = users.reduce((acc, user) => {
  acc[user.id] = {
    user,
    toys: [],
    books: []
  };
  return acc;
}, {});

/* Simple function what will append the item to the array */
const setUserData = (mappedById, items, key) => {
  items.forEach(item => mappedById[item.id] ? .[key] ? .push(item))
}

/* Look over the sub data sets */
setUserData(mappedById, toys, 'toys');
setUserData(mappedById, books, 'books');

/* Get the final array out of the users */
const result = Object.values(mappedById);

console.log(result);

另一种方法是Map所有数据源,并在循环访问用户时将它们组合起来。

  • 在每个数据集上循环(每个数据集减少X)
  • 遍历用户数据集(forEach)
/* Data */
const users = [
  {id: 1, name: 'Bob'}, 
  { id: 2, name: 'Al' }
];

const toys = [
  { id:1, name: 'foo'},
  { id:1, name: 'bar'},
  { id:2, name: 'baz'}
];

const books = [
  {id: 1, name: 'book1'}
]

// Function to build array by user id for the sub data
const setUserData = (acc, item) => {
  acc[item.id] = acc[item.id] || [];
  acc[item.id].push(item);
  return acc;
}

/* Look over the sub data sets */
const toysMapped = toys.reduce(setUserData, {});
const booksMapped = books.reduce(setUserData, {});

/* Build the user array with the sub data */
const result = users.map((user) => ({
  user,
  toys: toysMapped[user.id] || [],
  books: booksMapped[user.id] || []
}));

console.log(result);

相关问题