如何获取和设置一个无限深度数组对象的值之和?

问题描述 投票:0回答:1

我需要将对象数组转换为包含新类型字段的对象的新数组

percent
。任务是这样的 - 数组中的每个对象都有一个带有数值的
defaultWeight 
字段。在这个数组中,我必须将当前数组的
defaultWeight
添加到
sumArray
的总和,然后获取
defaultWeight
值,除以
sumArray
并乘以 100
(defaultWeight / sumArray * 100)
。因此,我得到了必须放入新
percent
字段中的数字的百分比,这些数组的深度将来不会遇到。救救我吧,我已经连续第二天绞尽脑汁了。下面是一个例子:

[
    {
        "id": 1,
        "name": "Блок «Тест1»",
        "weight": null,
        "defaultWeight": 0.3,
        "children": [
            {
                "id": 1,
                "name": "Планирование активностей",
                "weight": null,
                "defaultWeight": 1,
                "children": []
            },
            {
                "id": 2,
                "name": "Выполнение плана по визитам",
                "weight": null,
                "defaultWeight": 1,
                "children": []
            },
            {
                "id": 3,
                "name": "Выполнение плана по групповым мероприятиям",
                "weight": null,
                "defaultWeight": 1,
                "children": []
            },
            {
                "id": 4,
                "name": "Выполнение маркетинговой стратегии (включает три KPI)",
                "weight": null,
                "defaultWeight": 1,
                "children": [
                    {
                        "id": 5,
                        "name": "Охват базы",
                        "weight": null,
                        "defaultWeight": 1,
                        "children": []
                    },
                    {
                        "id": 6,
                        "name": "Соблюдение кратности посещения специалистов",
                        "weight": null,
                        "defaultWeight": 1,
                        "children": []
                    },
                    {
                        "id": 7,
                        "name": "Интервальность",
                        "weight": null,
                        "defaultWeight": 1,
                        "children": []
                    }
                ],
                "children": [
                    {
                        "id": 5,
                        "name": "Охват базы",
                        "weight": null,
                        "defaultWeight": 1,
                        "children": []
                    },
                    {
                        "id": 6,
                        "name": "Соблюдение кратности посещения специалистов",
                        "weight": null,
                        "defaultWeight": 1,
                        "children": []
                    },
                    {
                        "id": 7,
                        "name": "Интервальность",
                        "weight": null,
                        "defaultWeight": 1,
                        "children": []
                    }
                ]
            },
            {
                "id": 14,
                "name": "Время, проведённое на визитах в день",
                "weight": null,
                "defaultWeight": 1,
                "children": []
            },
            {
                "id": 15,
                "name": "Средняя длительность визита",
                "weight": null,
                "defaultWeight": 1,
                "children": []
            },
            {
                "id": 16,
                "name": "Доля рабочего дня на активности",
                "weight": null,
                "defaultWeight": 1,
                "children": []
            },
            {
                "id": 17,
                "name": "Геолокация",
                "weight": null,
                "defaultWeight": 1,
                "children": []
            }
        ]
    },
    {
        "id": 2,
        "name": "Блок «Тест2»",
        "weight": null,
        "defaultWeight": 0.2,
        "children": [
            {
                "id": 8,
                "name": "% выполнения «Двойной визит» (оценка РМа)",
                "weight": null,
                "defaultWeight": 1,
                "children": []
            },
            {
                "id": 9,
                "name": "% выполнения «Аудит» (оценка РМа)",
                "weight": null,
                "defaultWeight": 1,
                "children": []
            },
            {
                "id": 10,
                "name": "% выполнения «Двойной визит» (оценка Аудитора)",
                "weight": null,
                "defaultWeight": 1,
                "children": []
            },
            {
                "id": 11,
                "name": "% выполнения «Аудит» (оценка Аудитора)",
                "weight": null,
                "defaultWeight": 1,
                "children": []
            },
            {
                "id": 19,
                "name": "Средневзвешенное с весами оценки РМа и Аудитора",
                "weight": null,
                "defaultWeight": 1,
                "children": []
            }
        ]
    },
    {
        "id": 3,
        "name": "Блок «Тест3»",
        "weight": null,
        "defaultWeight": 0.5,
        "children": [
            {
                "id": 26,
                "name": "Выполнение плана продаж",
                "weight": null,
                "defaultWeight": 0.9,
                "children": []
            },
            {
                "id": 27,
                "name": "Темп прироста",
                "weight": null,
                "defaultWeight": 0.025,
                "children": []
            },
            {
                "id": 28,
                "name": "Evolution Index",
                "weight": null,
                "defaultWeight": 0.025,
                "children": []
            },
            {
                "id": 29,
                "name": "Динамика фактической доли на рынке",
                "weight": null,
                "defaultWeight": 0.025,
                "children": []
            },
            {
                "id": 30,
                "name": "Сравнение фактической доли на рынке с долей по РФ",
                "weight": null,
                "defaultWeight": 0.025,
                "children": []
            }
        ]
    }
]

应该变成:

[
    {
        "id": 1,
        "name": "Блок «SoReX»",
        "weight": null,
        "defaultWeight": 0.3,
        "children": [
            {
                "id": 1,
                "name": "Планирование активностей",
                "weight": null,
                "defaultWeight": 1,
                "children": [],
                "percent": 12.5
            },
            {
                "id": 2,
                "name": "Выполнение плана по визитам",
                "weight": null,
                "defaultWeight": 1,
                "children": [],
                "percent": 12.5
            },
            {
                "id": 3,
                "name": "Выполнение плана по групповым мероприятиям",
                "weight": null,
                "defaultWeight": 1,
                "children": [],
                "percent": 12.5
            },
            {
                "id": 4,
                "name": "Выполнение маркетинговой стратегии (включает три KPI)",
                "weight": null,
                "defaultWeight": 1,
                "children": [
                    {
                        "id": 5,
                        "name": "Охват базы",
                        "weight": null,
                        "defaultWeight": 1,
                        "percent": 33.33,
                        "children": []
                    },
                    {
                        "id": 6,
                        "name": "Соблюдение кратности посещения специалистов",
                        "weight": null,
                        "defaultWeight": 1,
                        "percent": 33.33,
                        "children": []
                    },
                    {
                        "id": 7,
                        "name": "Интервальность",
                        "weight": null,
                        "defaultWeight": 1,
                        "percent": 33.33,
                        "children": []
                    }
                ]
            {
                "id": 14,
                "name": "Время, проведённое на визитах в день",
                "weight": null,
                "defaultWeight": 1,
                "children": [],
                "percent": 12.5
            },
            {
                "id": 15,
                "name": "Средняя длительность визита",
                "weight": null,
                "defaultWeight": 1,
                "children": [],
                "percent": 12.5
            },
            {
                "id": 16,
                "name": "Доля рабочего дня на активности",
                "weight": null,
                "defaultWeight": 1,
                "children": [],
                "percent": 12.5
            },
            {
                "id": 17,
                "name": "Геолокация",
                "weight": null,
                "defaultWeight": 1,
                "children": [],
                "percent": 12.5
            }
        ],
        "percent": 30
    },
    {
        "id": 2,
        "name": "Блок «Качество»",
        "weight": null,
        "defaultWeight": 0.2,
        "children": [
            {
                "id": 8,
                "name": "% выполнения «Двойной визит» (оценка РМа)",
                "weight": null,
                "defaultWeight": 1,
                "children": [],
                "percent": 20
            },
            {
                "id": 9,
                "name": "% выполнения «Аудит» (оценка РМа)",
                "weight": null,
                "defaultWeight": 1,
                "children": [],
                "percent": 20
            },
            {
                "id": 10,
                "name": "% выполнения «Двойной визит» (оценка Аудитора)",
                "weight": null,
                "defaultWeight": 1,
                "children": [],
                "percent": 20
            },
            {
                "id": 11,
                "name": "% выполнения «Аудит» (оценка Аудитора)",
                "weight": null,
                "defaultWeight": 1,
                "children": [],
                "percent": 20
            },
            {
                "id": 19,
                "name": "Средневзвешенное с весами оценки РМа и Аудитора",
                "weight": null,
                "defaultWeight": 1,
                "children": [],
                "percent": 20
            }
        ],
        "percent": 20
    },
    {
        "id": 3,
        "name": "Блок «Рынок»",
        "weight": null,
        "defaultWeight": 0.5,
        "children": [
            {
                "id": 26,
                "name": "Выполнение плана продаж",
                "weight": null,
                "defaultWeight": 0.9,
                "children": [],
                "percent": 90
            },
            {
                "id": 27,
                "name": "Темп прироста",
                "weight": null,
                "defaultWeight": 0.025,
                "children": [],
                "percent": 2.5
            },
            {
                "id": 28,
                "name": "Evolution Index",
                "weight": null,
                "defaultWeight": 0.025,
                "children": [],
                "percent": 2.5
            },
            {
                "id": 29,
                "name": "Динамика фактической доли на рынке",
                "weight": null,
                "defaultWeight": 0.025,
                "children": [],
                "percent": 2.5
            },
            {
                "id": 30,
                "name": "Сравнение фактической доли на рынке с долей по РФ",
                "weight": null,
                "defaultWeight": 0.025,
                "children": [],
                "percent": 2.5
            }
        ],
        "percent": 50
    }
]

我尝试通过递归来解决这个问题,但不幸的是,我的算法知识还有很多不足之处

public setSum(weight: any, id?: number) {

const calculation = (weights) => weights.map(block => {
  return {
    ...block,
    percent: block.defaultWeight / this.sumBlock * 100
  };
});

if (weight.length !== []) {
  this.sumBlock = weight.reduce((acc, block) => {
    return acc += block.defaultWeight;
  }, 0);

  if (id) {
    this.cloneBlocks = this.cloneBlocks.map(item => {
      if (item.id === id) {
        return {
          ...item,
          groups: weight.map(block => {
            return {
              ...block,
              percent: block.defaultWeight / this.sumBlock * 100
            };
          })
        };
      } else {
        return { ...item };
      }
    });
    return;
  } else {
    this.cloneBlocks = weight.map(block => {
      return {
        ...block,
        percent: block.defaultWeight / this.sumBlock * 100
      };
    });
  }
}

weight.forEach(block => {
  if (block.groups) {
    this.setSum(block.groups, block.id);
  }
});

console.log(this.cloneBlocks);

}

javascript algorithm recursion binary-search-tree
1个回答
0
投票

我认为这样的东西应该可以完成工作,请参阅评论以了解其工作原理的详细信息:

// Start of Dataset
const dataset = [
    {
        "id": 1,
        "name": "Блок «Тест1»",
        "weight": null,
        "defaultWeight": 0.3,
        "children": [
            {
                "id": 1,
                "name": "Планирование активностей",
                "weight": null,
                "defaultWeight": 1,
                "children": []
            },
            {
                "id": 2,
                "name": "Выполнение плана по визитам",
                "weight": null,
                "defaultWeight": 1,
                "children": []
            },
            {
                "id": 3,
                "name": "Выполнение плана по групповым мероприятиям",
                "weight": null,
                "defaultWeight": 1,
                "children": []
            },
            {
                "id": 4,
                "name": "Выполнение маркетинговой стратегии (включает три KPI)",
                "weight": null,
                "defaultWeight": 1,
                "children": [
                    {
                        "id": 5,
                        "name": "Охват базы",
                        "weight": null,
                        "defaultWeight": 1,
                        "children": []
                    },
                    {
                        "id": 6,
                        "name": "Соблюдение кратности посещения специалистов",
                        "weight": null,
                        "defaultWeight": 1,
                        "children": []
                    },
                    {
                        "id": 7,
                        "name": "Интервальность",
                        "weight": null,
                        "defaultWeight": 1,
                        "children": []
                    }
                ],
                "children": [
                    {
                        "id": 5,
                        "name": "Охват базы",
                        "weight": null,
                        "defaultWeight": 1,
                        "children": []
                    },
                    {
                        "id": 6,
                        "name": "Соблюдение кратности посещения специалистов",
                        "weight": null,
                        "defaultWeight": 1,
                        "children": []
                    },
                    {
                        "id": 7,
                        "name": "Интервальность",
                        "weight": null,
                        "defaultWeight": 1,
                        "children": []
                    }
                ]
            },
            {
                "id": 14,
                "name": "Время, проведённое на визитах в день",
                "weight": null,
                "defaultWeight": 1,
                "children": []
            },
            {
                "id": 15,
                "name": "Средняя длительность визита",
                "weight": null,
                "defaultWeight": 1,
                "children": []
            },
            {
                "id": 16,
                "name": "Доля рабочего дня на активности",
                "weight": null,
                "defaultWeight": 1,
                "children": []
            },
            {
                "id": 17,
                "name": "Геолокация",
                "weight": null,
                "defaultWeight": 1,
                "children": []
            }
        ]
    },
    {
        "id": 2,
        "name": "Блок «Тест2»",
        "weight": null,
        "defaultWeight": 0.2,
        "children": [
            {
                "id": 8,
                "name": "% выполнения «Двойной визит» (оценка РМа)",
                "weight": null,
                "defaultWeight": 1,
                "children": []
            },
            {
                "id": 9,
                "name": "% выполнения «Аудит» (оценка РМа)",
                "weight": null,
                "defaultWeight": 1,
                "children": []
            },
            {
                "id": 10,
                "name": "% выполнения «Двойной визит» (оценка Аудитора)",
                "weight": null,
                "defaultWeight": 1,
                "children": []
            },
            {
                "id": 11,
                "name": "% выполнения «Аудит» (оценка Аудитора)",
                "weight": null,
                "defaultWeight": 1,
                "children": []
            },
            {
                "id": 19,
                "name": "Средневзвешенное с весами оценки РМа и Аудитора",
                "weight": null,
                "defaultWeight": 1,
                "children": []
            }
        ]
    },
    {
        "id": 3,
        "name": "Блок «Тест3»",
        "weight": null,
        "defaultWeight": 0.5,
        "children": [
            {
                "id": 26,
                "name": "Выполнение плана продаж",
                "weight": null,
                "defaultWeight": 0.9,
                "children": []
            },
            {
                "id": 27,
                "name": "Темп прироста",
                "weight": null,
                "defaultWeight": 0.025,
                "children": []
            },
            {
                "id": 28,
                "name": "Evolution Index",
                "weight": null,
                "defaultWeight": 0.025,
                "children": []
            },
            {
                "id": 29,
                "name": "Динамика фактической доли на рынке",
                "weight": null,
                "defaultWeight": 0.025,
                "children": []
            },
            {
                "id": 30,
                "name": "Сравнение фактической доли на рынке с долей по РФ",
                "weight": null,
                "defaultWeight": 0.025,
                "children": []
            }
        ]
    }
];

function setPercent(dataset) {
  // Sum the total defaultWeight for siblings
  const totalWeight = dataset.reduce((acc, next) => acc + next.defaultWeight, 0);
  dataset.forEach(node => {
    // Set percent of siblings
    node.percent = node.defaultWeight / totalWeight * 100;
    // Recurse for children
    setPercent(node.children);
  });
}

// Run function
setPercent(dataset);

console.log(dataset);

© www.soinside.com 2019 - 2024. All rights reserved.