Pu sh данные к родителю в рекурсивной функции - PullRequest
1 голос
/ 26 марта 2020

У меня есть следующий объект:

let model = {
   id: 1,
   name: "model 1",
   children: [{
         id: 2,
         name: "sub model 1",
         children: [{
               id: 3,
               name: "criteria 1",
               isCriteria: true,
               answer: {
                  mark: 4
               }
            },
            {
               id: 4,
               name: "criteria 2",
               isCriteria: true
            }
         ]
      },
      {
         id: 5,
         name: "sub model 2",
         children: [{
               id: 6,
               name: "criteria 3",
               isCriteria: true,
               answer: {
                  mark: 4
               }
            },
            {
               id: 7,
               name: "criteria 4",
               isCriteria: true,
               answer: {
                  mark: 2
               }
            }
         ]
      }
   ]
};

Я хочу в результате следующий объект:

{
   name: "model 1",
   answer: {
      mark: 3.5,
      completion: 75
   },
   children: [{
         name: "sub model 1",
         answer: {
            mark: 4,
            completion: 50
         },
         children: [{
               name: "criteria 1",
               isCriteria: true,
               answer: {
                  mark: 4
               }
            },
            {
               name: "criteria 2",
               isCriteria: true
            }
         ]
      },
      {
         name: "sub model 2",
         answer: {
            mark: 3,
            completion: 100
         },
         children: [{
               name: "criteria 3",
               isCriteria: true,
               answer: {
                  mark: 4
               }
            },
            {
               name: "criteria 4",
               isCriteria: true,
               answer: {
                  mark: 2
               }
            }
         ]
      }
   ]
}

EXPLICATION: Я хочу pu sh каждому родителю следующий объект ответа:

{
    mark: the sum of marks of all children/total of children (exclude children with no answer),
    completion: (the sum of children with answer/total children) * 100
}

!! NB. Глубина объекта неизвестна.

Я попробовал следующую функцию, но он добавляет объект ответа только к первому родителю до последней глубины

function loopThoughModelChildren(node, parent) {
    if (node == null) {
        return;
    };
    if (node.isCriteria) {
        if (!parent.tempAnswer) {
            parent.tempAnswer = [];
        }
        parent.tempAnswer.push({ child: node.id, answer: node.answer });
    }
    if (node.children)
        node.children.forEach(child => loopThoughModelChildren(child, node));
}

1 Ответ

3 голосов
/ 26 марта 2020

Вы можете использовать рекурсивный подход с использованием свойства children.

Затем создать новые узлы и назначить ответы.

function convert(node) {
    if (!node.children) return node;
    var marks = 0,
        completions = 0,
        count = 0,
        children = node.children.map(node => {
            node = convert(node);
            if (node.answer) {
                marks += node.answer.mark;
                completions += node.answer.completion || 100;
                count++;
            }
            return node;
        });
    return { ...node, answer: { mark: marks / count, completion: completions / node.children.length }, children };
}

var model = { id: 1, name: "model 1", children: [{ id: 2, name: "sub model 1", children: [{ id: 3, name: "criteria 1", isCriteria: true, answer: { mark: 4 } }, { id: 4, name: "criteria 2", isCriteria: true }] }, { id: 5, name: "sub model 2", children: [{ id: 6, name: "criteria 3", isCriteria: true, answer: { mark: 4 } }, { id: 7, name: "criteria 4", isCriteria: true, answer: { mark: 2 } }] }] },
    result = convert(model);

   console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...