Оптимизация алгоритмов в Node, Javascript

Учитывая следующий массив json

const groups=[{ id:1, parent:null, groupName:'Others', maxScore:3}, {id:2, parent:null, groupName: 'Group 1', maxScore:0}, {id:3, parent:2, groupName:'Others, maxScore:2}, {id:4, parent:2, groupName:'Sub Group 1', maxScore:1}];

Какой подход к суммированию maxScores в пределах родители был бы более ориентированным на производительность? Это похоже на древовидную структуру, но узлы не имеют ссылок на своих дочерних элементов.

Я пробую подход map.reduce прямо сейчас

function addMaxScoreToGroups(groups) {
    return groups.map((group) => {
      const newGroup = group;
      if (group.parent === null && group.name !== 'Others') {
        const children = groups.filter(elem => elem.parent === group.id);
          if (children) {
            newGroup.maxScore = children.map(x => x.maxScore)
           .reduce((value, acum) => value + acum);
          }
      }
      return newGroup;
    });
}

Ожидаемый результат будет

const groups=[{ id:1, parent:null, groupName:'Others', maxScore:3}, {id:2, parent:null, groupName: 'Group 1', maxScore:0,maxPosibleScore:3}, {id:3, parent:2, groupName:'Others, maxScore:2}, {id:4, parent:2, groupName:'Sub Group 1', maxScore:1}];

Вопросы, касающиеся Самый лучший...., очень субъективны. То, что выполняет Лучший для одного, может не работать для другого. Вы можете использовать jsPerf или аналогичные сайты / инструменты для тестирования производительности подходов / решений, которые работают / дают правильные результаты, и использовать то, что лучше всего соответствует вашему сценарию. - Если у вас еще нет рабочего решения, перефразируйте вопрос, чтобы сосредоточиться на нем.

Nope 25.04.2018 12:35

На самом деле он работает, но я думаю, что его можно оптимизировать с точки зрения того, сколько раз мне нужно использовать map.reduce, чтобы получить правильный результат.

user2821789 25.04.2018 13:45

Если ваш код работает, и вы ищете оптимизацию, codereview.stackexchange.com может дать вам лучшие ответы, поскольку такие вопросы обычно не по теме в Stackoverflow. Посмотрите, какие вопросы По теме и какие Не по теме

Nope 25.04.2018 17:23
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
3
61
1

Ответы 1

Итерируйте с помощью Array.reduce(). Для каждого объекта создайте новую запись (или обновите существующую в случае родительского) путем клонирования объекта с помощью распространение объекта (или Object.assign().

Если у объекта есть родительский объект, создайте его, если он не существует, и добавьте / обновите maxPossibleScore.

Преобразуйте обратно в массив с помощью Object.values().

const groups=[{ id:1, parent:null, groupName:'Others', maxScore:3}, {id:3, parent:2, groupName:'Others', maxScore:2}, {id:4, parent:2, groupName:'Sub Group 1', maxScore:1}, {id:2, parent:null, groupName: 'Group 1', maxScore:5}];
    
const ms = 'maxScore';
const mps = 'maxPossibleScore';
const result = Object.values(groups.reduce((r, o) => {
  // clone
  const c = { ...o };
  
  // if current parent initalized before, update maxPossibleScore
  if (!o.parent && r[o.id]) c[mps] = r[o.id][mps] + c[ms];
  
  r[o.id] = c;
  
  if (o.parent) {
    // if parent doesn't exist init
    r[o.parent] = r[o.parent] || {};
    // if parent.maxPossibleScore doesn't exist init it
    if (!(mps in r[o.parent])) {
      r[o.parent][mps] = r[o.parent][ms] || 0;
    }
    
    r[o.parent][mps] += o[ms];
  }
  
  return r;
}, {}));

console.info(result);

Наверное @nope :)

Ori Drori 25.04.2018 12:42

Почему? OP запросил более эффективный код, почему ваш код будет работать лучше, чем существующий код OP, и как вы это определяете? jsPerf или аналогичный?

Nope 25.04.2018 17:26

Обозначение Big O - O (n) против как минимум O (n ^ 2) (текущее решение). Поскольку мы используем reduce, которое вызывает функции обратного вызова, он менее эффективен, чем простой цикл for.

Ori Drori 25.04.2018 18:55

@OriDrori, это не работает :( Если у меня только один родитель = null, его maxPosibleScore остается 0

user2821789 26.04.2018 01:05

Должен быть исправлен сейчас. Если нет, добавьте тестовый пример в комментарии.

Ori Drori 26.04.2018 02:54

Другие вопросы по теме