Оптимизируйте код в JavaScript (в настоящее время используется слишком много циклов)

#javascript #for-loop #data-structures

#язык JavaScript #для-петли #структуры данных

Вопрос:

Я работал над вопросом о формировании данных и, наконец, получил ответ.

Однако в моем ответе слишком много циклов, и это замедлит временную сложность при реализации.

Ниже приведен мой код:

 const userInfo = [];  for (let i = 0; i lt; projects.length; i  ) {  const userProject = projects[i].userProjects;   for (let j = 0; j lt; userProject.length; j  ) {  const userExist = userInfo.some((item) =gt;  item.userId.includes(userProject[j].user.userId)  );  if (!userExist) userInfo.push(userProject[j].user);  } }  userInfo.forEach((user) =gt; {  let tempArr = [];  for (let i = 0; i lt; projects.length; i  ) {  const userProject = projects[i].userProjects;  for (let j = 0; j lt; 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 вместе, но это не сработало…

Пожалуйста, помогите. Большое вам спасибо!!!

Комментарии:

1. Что вам нужно, так это лучшая структура данных, организованная в соответствии с тем, что должно делать ваше приложение.

2. Поделитесь своими данными и, пожалуйста, расскажите, каков ожидаемый результат

Ответ №1:

В верхней части два внешних цикла выглядят необходимыми (поскольку у вас есть N проектов * M пользовательских проектов), но третий .some — нет-измените userInfo массив на отображение идентификаторов пользователей для их пользователей, поэтому во втором цикле вам нужно только посмотреть, существует ли идентификатор пользователя ( O(1) ), и назначить, если это не так.

Вместо назначения пользователя назначьте объект нужной вам формы в конце — a [{ 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 =gt; {  user,  projects: [  { projectId, name },  ...  

Если вам нужна точная структура данных, которую дает вам ваш текущий код, затем выполните:

 const output = [...userProjectsByUserId.values()]  .map(({ user, projects }) =gt; ({ ...user, project: projects }));  

(хотя вы могли бы рассмотреть возможность использования projects вместо project , так как это коллекция проектов, а не один проект)

Комментарии:

1. Огромное спасибо. Что делать, если не использовать новую карту структуры данных (), а вместо этого использовать массив?

2. Если вы используете массив, вы не сможете сразу найти в нем идентификатор пользователя — вместо этого вам придется искать в массиве совпадение ( O(n) ) вместо того, чтобы просто искать его как свойство карты или объекта ( O(1) ). Поэтому не используйте массив при группировке; это сделает вещи слишком неэффективными.

3. Понял, большое вам спасибо за вашу помощь!!