优化 JavaScript 中的代码(目前使用了太多的 for 循环)
Optimize code in JavaScript (Currently using too many for loops)
一直在做一道数据格式化题,终于有了答案
但是我的回答循环太多,执行的时候会降低时间复杂度。
下面是我的代码:
const userInfo = [];
for (let i = 0; i < projects.length; i++) {
const userProject = projects[i].userProjects;
for (let j = 0; j < userProject.length; j++) {
const userExist = userInfo.some((item) =>
item.userId.includes(userProject[j].user.userId)
);
if (!userExist) userInfo.push(userProject[j].user);
}
}
userInfo.forEach((user) => {
let tempArr = [];
for (let i = 0; i < projects.length; i++) {
const userProject = projects[i].userProjects;
for (let j = 0; j < userProject.length; j++) {
if (user.userId === userProject[j].userId)
tempArr.push({
projectId: projects[i].projectId,
name: projects[i].name,
});
}
}
user.project = tempArr;
});
console.log(userInfo);
有什么方法可以优化我的代码吗?我尝试将嵌套的 for 循环组合在一起但没有用...
请帮忙。非常感谢!!!
在顶部,外面的两个循环看起来是必要的(因为您有 N 个项目 * M 个用户项目),但第三个 .some
不是 - 将 userInfo
从数组更改为userIds 到他们的用户的映射,所以在第二个循环中,你只需要查找 userId 是否已经存在(O(1)
),如果不存在则分配。
不是分配用户,而是在最后分配一个您需要的形状的对象 - [{ projectId, name }]
。这将使您不必再次遍历整个数组 - 一旦您检查了是否需要为 userId
创建周围数组,您就可以将对象推送到数组,无论您是否是否必须在该迭代中创建数组。
const userProjectsByUserId = new Map();
for (const { userProjects, projectId, name } of projects) {
for (const { user } of projects) {
if (!userProjectsByUserId.has(user.userId)) {
userProjectsByUserId.set(user.userId, { user, projects: [] }]);
}
userProjectsByUserId.get(user.userId).projects.push({ projectId, name });
}
}
这将为您提供形状的地图
userId => {
user,
projects: [
{ projectId, name },
...
如果您需要当前代码为您提供的精确数据结构,然后执行以下操作:
const output = [...userProjectsByUserId.values()]
.map(({ user, projects }) => ({ ...user, project: projects }));
(尽管您可能会考虑使用 projects
而不是 project
,因为它是项目的集合,而不是单个项目)
一直在做一道数据格式化题,终于有了答案
但是我的回答循环太多,执行的时候会降低时间复杂度。
下面是我的代码:
const userInfo = [];
for (let i = 0; i < projects.length; i++) {
const userProject = projects[i].userProjects;
for (let j = 0; j < userProject.length; j++) {
const userExist = userInfo.some((item) =>
item.userId.includes(userProject[j].user.userId)
);
if (!userExist) userInfo.push(userProject[j].user);
}
}
userInfo.forEach((user) => {
let tempArr = [];
for (let i = 0; i < projects.length; i++) {
const userProject = projects[i].userProjects;
for (let j = 0; j < userProject.length; j++) {
if (user.userId === userProject[j].userId)
tempArr.push({
projectId: projects[i].projectId,
name: projects[i].name,
});
}
}
user.project = tempArr;
});
console.log(userInfo);
有什么方法可以优化我的代码吗?我尝试将嵌套的 for 循环组合在一起但没有用...
请帮忙。非常感谢!!!
在顶部,外面的两个循环看起来是必要的(因为您有 N 个项目 * M 个用户项目),但第三个 .some
不是 - 将 userInfo
从数组更改为userIds 到他们的用户的映射,所以在第二个循环中,你只需要查找 userId 是否已经存在(O(1)
),如果不存在则分配。
不是分配用户,而是在最后分配一个您需要的形状的对象 - [{ projectId, name }]
。这将使您不必再次遍历整个数组 - 一旦您检查了是否需要为 userId
创建周围数组,您就可以将对象推送到数组,无论您是否是否必须在该迭代中创建数组。
const userProjectsByUserId = new Map();
for (const { userProjects, projectId, name } of projects) {
for (const { user } of projects) {
if (!userProjectsByUserId.has(user.userId)) {
userProjectsByUserId.set(user.userId, { user, projects: [] }]);
}
userProjectsByUserId.get(user.userId).projects.push({ projectId, name });
}
}
这将为您提供形状的地图
userId => {
user,
projects: [
{ projectId, name },
...
如果您需要当前代码为您提供的精确数据结构,然后执行以下操作:
const output = [...userProjectsByUserId.values()]
.map(({ user, projects }) => ({ ...user, project: projects }));
(尽管您可能会考虑使用 projects
而不是 project
,因为它是项目的集合,而不是单个项目)