I have an array of categories:
[
{ categoryId: '01', categoryName: 'Byggmaterial' },
{ categoryId: '010', categoryName: 'Bindemedel och bruk' },
{ categoryId: '01001', categoryName: 'Cement' },
{ categoryId: '01002', categoryName: 'Bruksbindemedel' },
{ categoryId: '01003', categoryName: 'Kalkvaror' },
{ categoryId: '011', categoryName: 'Byggnadsblock och ballast' },
{ categoryId: '01101', categoryName: 'Betongblock' },
{ categoryId: '01102', categoryName: 'Tegel' },
{ categoryId: '02', categoryName: 'Byggmaterial' },
{ categoryId: '020', categoryName: 'Bindemedel och bruk' },
{ categoryId: '02001', categoryName: 'Cement' },
{ categoryId: '02002', categoryName: 'Bruksbindemedel' }
......
]
And an array of products:
[
{
productNumber: '01405',
productName: 'SERVALAC AQUA BLANK - Utg�tt'
},
{
productNumber: '01405',
productName: 'SERVALAC AQUA HALVBLANK - Utg�tt'
},
{
productNumber: '03405',
productName: 'SERVALAC AQUA HALVBLANK - Utg�tt'
},
{ productNumber: '03404', productName: 'SCOTTE GT-20 - UTG�TT' },
{ productNumber: '03404', productName: 'SCOTTE 7 - UTG�TT' },
{ productNumber: '03404', productName: 'SCOTTE 7 - UTG�TT' },
{ productNumber: '03404', productName: 'SCOTTE 7 - UTG�TT' },
{ productNumber: '03404', productName: 'SCOTTE 5 - UTG�TT' },
{ productNumber: '03404', productName: 'SCOTTE 20 - UTG�TT' },
......
]
I want to group each product in the corresponding category. The categories should be also grouped like this: main category (all the categories with 2 digits), second category (with 3 digits) and the next one (with 5 digits). Each product should be added to the corresponding main category, second and third category.
The result should be like this:
{
"id":"01",
"categoryName":"Byggmaterial",
"items":[
{
"id":"010",
"categoryName":"Bindemedel och bruk",
"items": [
{
"id":"01001",
"categoryName":"Cement",
"products": [
{
"productNumber":"01001",
"productName":"Tunnfog och Tunnputsbruk A"
},
{
"productNumber":"01001",
"productName":"Tunnfog"
},
.......
]
}
]
},
I'm stuck so I need help. I've tried with "for loop" inside "for loop", but I only succeeded to group all the products in main category.
{"id":"01","categoryName":"Byggmaterial","items":[{"productNumber":"01001","productName":"Tunnfog och Tunnputsbruk A"},{"productNumber":"01001","productName":"Lagningsmassa fin"},{"productNumber":"01399","productName":"Golvfoam Premium MFR"}, {"productNumber":"01199","productName":"THERMOMUR 350 STD SLUTET"}, {"productNumber":"01701","productName":"Adva Flow 484"},{"productNumber":"01706","productName":"Pieri Decobio C-23"}
Is there any other solution then "for loop"? I think that I cannot get the wanted result with only for loop. Thank you in advance!
You can use two mutually recursive helper functions: one that selects subcategories for the given category:
function items(cid, level) {
return categories
.filter(c => c.categoryId.startsWith(cid) && c.categoryId.length === level)
.map(process)
}
and one that processes a category:
function process(cat) {
let cid = cat?.categoryId || ''
switch (cid.length) {
case 0:
return {...cat, items: items(cid, 2)}
case 2:
return {...cat, items: items(cid, 3)}
case 3:
return {...cat, items: items(cid, 5)}
case 5:
return {
...cat,
products: products.filter(p => p.productNumber.startsWith(cid))
}
}
}
Finally, just invoke process()
with no arguments.
You could build the catalog by preserving all categoryId
which points to items
and later push the products to the category.
const
categories = [{ categoryId: '01', categoryName: 'Byggmaterial' }, { categoryId: '010', categoryName: 'Bindemedel och bruk' }, { categoryId: '01001', categoryName: 'Cement' }, { categoryId: '01002', categoryName: 'Bruksbindemedel' }, { categoryId: '01003', categoryName: 'Kalkvaror' }, { categoryId: '011', categoryName: 'Byggnadsblock och ballast' }, { categoryId: '01101', categoryName: 'Betongblock' }, { categoryId: '01102', categoryName: 'Tegel' }, { categoryId: '02', categoryName: 'Byggmaterial' }, { categoryId: '020', categoryName: 'Bindemedel och bruk' }, { categoryId: '02001', categoryName: 'Cement' }, { categoryId: '02002', categoryName: 'Bruksbindemedel' }],
products = [{ productNumber: "01001", productName: "Tunnfog och Tunnputsbruk A" }, { productNumber: "01001", productName: "Tunnfog" }],
catalog = categories.reduce((r, { categoryId, categoryName }) => {
let i = categoryId.length;
do {
const key = categoryId.slice(0, i);
if (key in r) {
(r[key].items ??= []).push(r[categoryId] = { categoryId, categoryName });
return r;
}
} while (--i)
r.items.push(r[categoryId] = { categoryId, categoryName });
return r;
}, { items: [] });
products.forEach(o => (catalog[o.productNumber].product ??= []).push(o));
console.log(catalog.items);
.as-console-wrapper { max-height: 100% !important; top: 0; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With