Разбор, пересчет вложенных объектов
- есть объект продукта
- в нем компоненты, из которых состоит продукт
- компоненты представлены в виде вложенных объектов
- компонент может быть простым или комплексным
- для простых компонентов и комплексных (первого уровня вложенности) указано необходимое количество для создания продукта
- у комплексных компонентов есть пустой объект, который должен быть заполнен в процессе разбора вложенных
let product = {
'VOP': { complex: true, count: 51, consist: {} },
'gem': { complex: false, count: 2 }
}
- есть объект комплексных компонентов
- комплексные компоненты содержат простые и комплексные (N-вложенность)
- для вложенных компонентов указано количество, необходимое для создания одного компонента, в составе которого он находится
let complexRes = {
'VOP': {
'vrs': { complex: false, count: 3 },
'sop': { complex: false, count: 1 },
'CBP': { complex: true, count: 3, consist: { } }
},
'CBP': {
'ab': { complex: false, count: 10 }
}
}
- Нужно сделать пересчет количества вложенных компонентов и модифицировать объект product
- В резльтате должны получить такое:
product = {
'VOP': { complex: true, count: 51, consist: {
'vrs': { complex: false, count: 153 },
'sop': { complex: false, count: 51 },
'CBP': { complex: true, count: 153, consist: {
'ab': { complex: false, count: 1530 }
} }
} },
'gem': { complex: false, count: 2 }
}
Пробовал делать в таком духе, но запутался
let complexConsist = {}
for(let key in product) {
if(product[key]['complex']){
calc(key, product[key]);
}
}
function calc(key, obj) {
complexConsist[key] = JSON.parse(JSON.stringify(obj));
for(let keyInner in complexRes[key]) {
if(complexRes[key][keyInner]['complex']) {
// дальше запутался, наговнокодил, выкладывать нет смысла видимо )
}
}
}
Может кто понял, что требуется и поможет дописать? )
UPD: вариант посложнее:
const complexResInit = {
'VOP': {
'vrs': { complex: false, count: 3 },
'sop': { complex: false, count: 1 },
'CBP': { complex: true, count: 3, consist: { } }
},
'CBP': {
'ab': { complex: false, count: 10 }
},
'MM': {
'mold': { complex: false, count: 10 },
'VOP': { complex: true, count: 10, consist: { } }
}
}
const productInit = {
'VOP': { complex: true, count: 51, consist: {} },
'gem': { complex: false, count: 2 },
'MM': { complex: true, count: 1, consist: {} }
}
Ответы (1 шт):
Автор решения: SwaD
→ Ссылка
Для обхода однотипных многоуровневых объектов используют рекурсию
const complexResInit = {
'VOP': {
'vrs': { complex: false, count: 3 },
'sop': { complex: false, count: 1 },
'CBP': { complex: true, count: 3, consist: { } }
},
'CBP': {
'ab': { complex: false, count: 10 }
},
'MM': {
'mold': { complex: false, count: 10 },
'VOP': { complex: true, count: 10, consist: { } }
}
}
const productInit = {
'VOP': { complex: true, count: 51, consist: {} },
'gem': { complex: false, count: 2 },
'MM': { complex: true, count: 1, consist: {} }
}
function compareProducts(product, complexRes, multiplier = 1) {
const res = {};
for(let key in product) {
res[key] = { ...product[key] };
res[key].count *= multiplier;
if (product[key].complex) res[key].consist = compareProducts(complexRes[key], complexRes, res[key].count)
}
return res;
}
const result = compareProducts(productInit, complexResInit)
console.log(result);
Для правильного составления рекурсивного обхода, надо понять, по каким признакам определять, что надо запустить рекурсию и что передавать на следующую итерацию.
В случае с вашими объектами, мы бежим по объекту продуктов и если попадается комплексный, то вызывам рекурсивно функцию и передаем уже не элемент из продуктов, а элемент из комплексных продуктов и его уже добавляем в результирующий объект
Еще пример рекурсии "на массивах":
function compareProductsArray(product, complexRes, multiplier = 1) {
return Object.entries(product).reduce((acc, [key, val]) => {
acc[key] = { ...val };
acc[key].count *= multiplier;
if (val.complex) acc[key].consist = compareProductsArray(complexRes[key], complexRes, acc[key].count);
return acc;
}, {});
}