Насколько я понимаю, каждый объект данного массива будет либо root, либо дочерним по отношению к другому root объекту. Я не знаю, ошибочно ли вы заполнили массив subSkills объекта или это следует учитывать, поэтому его следует заменить на весь объект, если он найден? согласно моему предположению, у меня просто нет subSkills в виде строк, я установил все subSkills на пустой массив для начала, дайте мне знать, следует ли это учитывать, пожалуйста. в противном случае вы можете просто увидеть, соответствует ли строка, тогда вы можете удалить ее из массива и заменить ее самим дочерним объектом.
Вот мое решение:
const givenArray = [
{
name: "chess",
subSkills: [],
parentId: "games",
_id: "chess",
},
{
name: "games",
subSkills: [],
parentId: "",
_id: "games",
},
{
name: "programming dev",
subSkills: [],
parentId: "chess",
_id: "programming",
},
{
name: "basketball 01",
subSkills: [],
parentId: "chess",
_id: "basketball",
},
];
const skillsAggregator = (skills) => {
const newSkills = [...skills];
newSkills.forEach((skill) => {
if (!!skill.parentId.length) {
addSubSkills(newSkills, skill);
}
});
return newSkills;
};
const addSubSkills = (skills, currentSkill) => {
for (let i = 0; i < skills.length; i++) {
const skill = skills[i];
if (currentSkill.parentId === skill._id) {
skill.subSkills.push(currentSkill);
break;
}
}
};
console.log(JSON.stringify(skillsAggregator(givenArray), null, 2));
ПРИМЕЧАНИЕ Если вы можете обновить структуру данных (а вы можете) до Map или литерального объекта, алгоритм будет быстрее, чем с массивом, вот пример с дополнительным уровнем вложенности:
const givenArray = {
chess: {
name: "chess",
subSkills: [],
parentId: "games",
_id: "chess",
},
games: {
name: "games",
subSkills: [],
parentId: "",
_id: "games",
},
programming: {
name: "programming dev",
subSkills: [],
parentId: "chess",
_id: "programming",
},
basketball: {
name: "basketball 01",
subSkills: [],
parentId: "chess",
_id: "basketball",
},
football: {
name: "football",
subSkills: [],
parentId: "basketball",
_id: "football",
},
};
const skillsAggregator = (skills) => {
const newSkills = { ...skills };
Object.entries(newSkills).forEach(([id, skill]) => {
if (!!skill.parentId.length) {
newSkills[skill.parentId].subSkills.push(skill);
}
});
return newSkills;
};
console.log(JSON.stringify(skillsAggregator(givenArray), null, 2));