Say I have a data structure like so.
child: [
{
typeOfPackage: 'subSub',
parents: '/Test123/Diet/',
itemName: '250 ML',
pricePerItem: 150,
quantity: 0,
quantityType: '123',
description: '5',
avgTimeTaken: 0,
images: [],
isEnabled: true,
inventory: [],
equipment: [],
_id: 617f9efdf0347931684888fd
},
{
typeOfPackage: 'sub',
parents: '/Test123/',
itemName: 'Regular',
pricePerItem: 0,
quantity: 0,
quantityType: '1',
description: '1',
avgTimeTaken: 1,
images: [],
isEnabled: true,
inventory: [],
equipment: [],
_id: 617f9efdf0347931684888fe
},
{
typeOfPackage: 'subSub',
parents: '/Test123/Reg3/',
itemName: '500ML',
pricePerItem: 123,
quantity: 0,
quantityType: '12',
description: '123',
avgTimeTaken: 51,
images: [],
isEnabled: true,
inventory: [],
equipment: [],
_id: 617f9efdf0347931684888ff
}
]
I intend to transform this data by splitting parents. And my intended result looks as follows:
child: [
{
itemName: 'Test123',
subPackages: [
{
itemName: 'Diet',
subSubPackages: [{
typeOfPackage: 'subSub',
parents: '/Test123/Diet/',
itemName: '250 ML',
pricePerItem: 150,
quantity: 0,
quantityType: '123',
description: '5',
avgTimeTaken: 0,
images: [],
isEnabled: true,
inventory: [],
equipment: [],
}]
},
{
itemName: 'Regular',
typeOfPackage: 'sub',
parents: '/Test123/',
pricePerItem: 0,
quantity: 0,
quantityType: '1',
description: '1',
avgTimeTaken: 1,
images: [],
isEnabled: true,
inventory: [],
equipment: [],
subSubPackages: [],
},
{
itemName: 'Reg3',
subSubPackages: [
{
typeOfPackage: 'subSub',
parents: '/Test123/Reg3/',
itemName: '500ML',
pricePerItem: 123,
quantity: 0,
quantityType: '12',
description: '123',
avgTimeTaken: 51,
images: [],
isEnabled: true,
inventory: [],
equipment: [],
_id: 617f9efdf0347931684888ff
}
]
},
]
}
]
I tried using lodash's chain and groupBy but I could only get as far as grouping it by the first itemName (Test123). I could not figure out how to do further grouping inside that without using a custom for loop and map methods and that too confused me.
CodePudding user response:
You could split parents
and build a nested structure.
This approach takes an shadow object for a faster access to same named parents and returns only the payload without organizing structure.
If you like to use subPackages
or subSubPackages
, you could take a function for generating this key along with the actuyl nesting level. For later processing data, I recommend to use only generic names, like children
for every level.
const
getSub = level => `sub${'Sub'.repeat(level)}Level`,
data = [{ typeOfPackage: 'subSub', parents: '/Test123/Diet/', itemName: '250 ML', pricePerItem: 150, quantity: 0, quantityType: '123', description: '5', avgTimeTaken: 0, images: [], isEnabled: true, inventory: [], equipment: [], _id: '617f9efdf0347931684888fd' }, { typeOfPackage: 'sub', parents: '/Test123/', itemName: 'Regular', pricePerItem: 0, quantity: 0, quantityType: '1', description: '1', avgTimeTaken: 1, images: [], isEnabled: true, inventory: [], equipment: [], _id: '617f9efdf0347931684888fe' }, { typeOfPackage: 'subSub', parents: '/Test123/Reg3/', itemName: '500ML', pricePerItem: 123, quantity: 0, quantityType: '12', description: '123', avgTimeTaken: 51, images: [], isEnabled: true, inventory: [], equipment: [], _id: '617f9efdf0347931684888ff' }],
result = data
.reduce((r, o) => {
o
.parents
.split('/')
.filter(Boolean)
.reduce((t, itemName, i) => {
if (!t[itemName]) {
t[itemName] = { _: [] };
t._.push({ itemName, [getSub(i)]: t[itemName]._ });
}
return t[itemName];
}, r)
._
.push(o);
return r;
}, { _: [] })
._;
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>