技术实践

我将循环从 100K 减少到 1K

这种修改后的方法比原始版本更快,因为它减少了为每个电子邮件 ID 查找匹配用户对象所需的迭代次数。该函数无需为每个电子邮件 ID 搜索用户数

羊先生的头像
羊先生2023.03.10 · 2 分钟阅读 · 36 阅读
我将循环从 100K 减少到 1K封面
文章正文还需 2 分钟

在处理项目时,我想为我拥有的电子邮件 ID 数组返回名称数组

js 复制代码
const users = [
   {name: 'John', email: 'john@example.com'},
   {name: 'Jane', email: 'jane@example.com'},
   {name: 'Bob', email: 'bob@example.com'}
];


function getNames(emailIds) {
   return emailIds.map((emailId)=>{
      const user = users.find((user)=>{
          return user.email === emailId
      });
      return user?.name || emailId
   })
}

如您所见,上面的代码,时间复杂度为O(nm). 换句话说,假设emailIds数组大小为 100 并且users数组大小为 1000 那么上面的代码可以运行 1000100 = 100000,所以为了减少迭代

js 复制代码
function getNames(emailIds) {
   const emailMap= {};

   users.forEach((user)=>{
      emailMap[user.email]=user.name
   });

   return emailIds.map((emailId)=>{
      return emailMap[emailId] || emailId
   })
}

该函数首先初始化一个空对象emailMap。然后它使用该方法遍历用户数组forEach()并将每个电子邮件到名称的映射存储在emailMap对象中,其中电子邮件是键,名称是值。

现在时间复杂度是O(n+m)。换句话说,上面的代码可能会运行1000+100 = 1100

这种修改后的方法比原始版本更快,因为它减少了为每个电子邮件 ID 查找匹配用户对象所需的迭代次数。该函数无需为每个电子邮件 ID 搜索用户数组,只需对用户数组执行一次迭代即可创建电子邮件到姓名的映射。随后的查找是使用 emailMap 对象中的恒定时间键查找完成的。