Untitled

 avatar
unknown
plain_text
2 years ago
2.0 kB
3
Indexable
function gatherInfo(input) {
  const atomicInfoSet = new Set();

  function processNode(node) {
    const { info, children } = node;

    for (const [key, value] of Object.entries(info)) {
      const atomicInfo = `info_${key}_${value}`;
      atomicInfoSet.add(atomicInfo);
    }

    const childInfo = children.map((child) => processNode(child));

    // Удаление свойств, которые наследуются от родительского узла
    const inheritedInfo = Object.entries(info).filter(([key, value]) => {
      return childInfo.every((child) => child.inheritedInfo.has(key) && child.inheritedInfo.get(key) === value);
    });
    const ownInfo = Object.fromEntries(inheritedInfo);
    const remainingInfo = Object.fromEntries(Object.entries(info).filter(([key]) => !(key in ownInfo)));

    // Обновление родительского узла с отсутствующими свойствами
    const parentMissingInfo = childInfo.reduce((missing, child) => {
      for (const [key, value] of child.inheritedInfo.entries()) {
        if (!missing.has(key)) {
          missing.set(key, value);
        } else if (missing.get(key) !== value) {
          missing.delete(key);
        }
      }
      return missing;
    }, new Map());

    const updatedInfo = { ...remainingInfo, ...Object.fromEntries(parentMissingInfo) };

    return { ownInfo, inheritedInfo: new Map(Object.entries(updatedInfo)), children: childInfo };
  }

  const root = processNode(input);
  const atomicInfo = Array.from(atomicInfoSet).sort();

  function buildResultNode(node) {
    const { ownInfo, inheritedInfo, children } = node;
    const info = Object.keys(ownInfo).sort().map((key) => `info_${key}_${ownInfo[key]}`);
    const updatedChildren = children.map(buildResultNode);
    return { info, children: updatedChildren };
  }

  const result = {
    atomicInfo,
    tree: buildResultNode(root),
  };

  return result;
}

module.exports = gatherInfo;
Editor is loading...