Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to get and set the sum of the values of an array object with infinite depth of this array?

I need to convert an array of objects into a new array with objects including a new type field
percent. The task is this – each object in the array has a defaultWeight field with a numeric value. In this array, I have to add the defaultWeight of the current array to the sum of sumArray, then I take the defaultWeight value, divide by sumArray and multiply by 100 (defaultWeight / sumArray * 100). Thus, I get the percentage of the number that I have to put in the new percent field, which depth of these arrays would not be encountered in the future. Help me, I’ve been racking my head for the second day. Below is an example:

[
    {
        "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": []
            }
        ]
    }
]

Should turn into:

[
    {
        "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
    }
]

I tried to solve this problem by recursion, but my knowledge of algorithms, unfortunately, leaves much to be desired

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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);

}

>Solution :

I think something like this should do the job, see comments for details on how it works:

// Start of Dataset
const object = [
    {
        "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": []
            }
        ]
    }
];

// Note: This function will mutate its parameter
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 if totalWeight is different from 0
    if (totalWeight !== 0) {
      node.percent = node.defaultWeight / totalWeight * 100;
    }
    // Recurse for children
    setPercent(node.children);
  });
}

// Run function, but clone object to avoid mutation
const dataset = structuredClone(object);
setPercent(dataset);

console.log(dataset);
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading