NodeJS Javascript减少了将数组转换为对象所花费的时间

s6fujrry  于 2023-02-21  发布在  Node.js
关注(0)|答案(3)|浏览(129)

我有两个数组列表。一个有50个元素(users),另一个有20000个元素(allUsers)。我必须根据它们是否存在于allUsers中来过滤users
为此,我将allUsers转换为对象,并使用该对象过滤掉users
allUsers是具有3个键对象的数组。
所以,从数组创建对象花费了太多的时间。我怎样才能减少整个操作的时间呢?

const usersMap = allUsers.reduce((aa, user) => {
    acc = { ...aa, [user.id]: user }
    return aa
  }, {})

  const matchedUsers = users.reduce((aa, user) => {
    const mappedUser = usersMap[user.id]
    if (mappedUser) {
      aa.push(mappedUser)
    }
    return aa
  }, [])
xxe27gdn

xxe27gdn1#

你使用spread肯定会减慢这个过程。{ ...aa, [user.id]: user }在每次迭代中都会创建一个新对象,而不仅仅是添加一个新属性,这样做就必须再次迭代spread对象的每个属性,从而使你的reduce方法成为O(n^2),而不是O(n)。
您可以从删除不必要的spread并在accumulator中分配一个新属性来提高reduce的效率开始。

const usersMap = allUsers.reduce((aa, user) => {
    aa[user.id] = user;
    return aa;
}, {});

或者您可以尝试使用Map

const usersMap = new Map(allUsers.map((user) => [user.id, user]));

const matchedUsers = users.reduce((aa, user) => {
  if (usersMap.has(user.id)) {
    aa.push(usersMap.get(user.id));
  }
  return aa;
}, []);
kuhbmx9i

kuhbmx9i2#

const lookup = new Set(users.map(x => x.id));
const matchedUsers = allUsers.filter(x => lookup.has(x.id));

代替
1.构建包含2万个项目的Map
1.浏览50个项目,尝试将其与Map关联起来
1.返回所有匹配的Map值的数组
把行动反过来
1.找50个身份证来比对。
1.从allUsers中提取最多50个具有匹配ID的项目。
由于没有从这20k个项目创建对象,因此这将从创建一个到创建零的时间减少了。

krcsximq

krcsximq3#

users.filter(user => allUsers.find(u => u.id === user.id))

筛选未在所有用户中找到的用户。

相关问题