Reputation: 498
Here is an array of objects with categories and the solution each category belongs to. Solutions are repeated but categories are unique.
const categories = [
{ category: 'Patch Leads', solution: 'Data Solutions' },
{ category: 'Cables', solution: 'Data Solutions' },
{ category: 'Nails', solution: 'Hardware' },
{ category: 'Locks', solution: 'Hardware' },
{ category: 'Screws', solution: 'Hardware' },
{ category: 'Cabinets', solution: 'Cabinet Solutions' },
{ category: 'Swing Frames', solution: 'Cabinet Solutions' },
{ category: 'Racks', solution: 'Cabinet Solutions' },
{ category: 'Fire Cables', solution: 'Fire Solutions' },
];
I need to return a new solutions array of solution objects. This is the format of the final result. All of the data to get this format is available when looping like index for the id's but I just can't get the format of my code right.
const solutions = [
{
id: "0",
name: "Data Solutions",
categories: [
{
id: "0",
name: "Cables",
slug: "cables"
},
{
id: "1",
name: "Patch Leads",
slug: "patch-leads"
}
]
},
{
id: "1",
name: "Hardware",
categories: [
{
id: "0",
name: "Nails",
slug: "nails"
},
{
id: "1",
name: "Locks",
slug: "locks"
},
{
id: "2",
name: "Screws",
slug: "screws"
}
]
},
{
id: "2",
name: "Cabinet Solutions",
categories: [
{
id: "0",
name: "Cabinets",
slug: "cabinets"
},
{
id: "1",
name: "Swing Frames",
slug: "swing-frames"
},
{
id: "2",
name: "Racks",
slug: "racks"
}
]
},
{
id: "3",
name: "Fire Solutions",
categories: [
{
id: "0",
name: "Fire Cables",
slug: "gire-cables"
}
]
}
]
Upvotes: 1
Views: 374
Reputation: 12988
You can use some classes to make to recreate objects faster.
const categories = [
{ category: 'Patch Leads', solution: 'Data Solutions' },
{ category: 'Cables', solution: 'Data Solutions' },
{ category: 'Nails', solution: 'Hardware' },
{ category: 'Locks', solution: 'Hardware' },
{ category: 'Screws', solution: 'Hardware' },
{ category: 'Cabinets', solution: 'Cabinet Solutions' },
{ category: 'Swing Frames', solution: 'Cabinet Solutions' },
{ category: 'Racks', solution: 'Cabinet Solutions' },
{ category: 'Fire Cables', solution: 'Fire Solutions' },
];
class category{
constructor(id,name){
this.id = id;
this.name = name;
this.slug = name;
}
}
class NewOne {
constructor(id,name,categories=[]) {
this.id = id;
this.name = name;
this.categories = categories;
}
}
let solutions = [];
solutions.push(new NewOne(0, categories[0].solution,[new category(0,categories[0].category)]));
let newArrayIndex = 0;
let idPlusOne = 1;
for(index in categories){
if(solutions[newArrayIndex].name !== categories[index].solution){
solutions.push(new NewOne(index, categories[index].solution,[new category(0,categories[index].category)]));
newArrayIndex++;
idPlusOne=1;
}else{
solutions[newArrayIndex].categories.push(new category(idPlusOne,categories[index].category));
idPlusOne++;
}
}
Upvotes: 0
Reputation: 6643
You can use reduce() method to do that. While iterating, if current item already exists then append current category to existing item. If not, create a new item with current category.
const categories = [ { category: 'Patch Leads', solution: 'Data Solutions' }, { category: 'Cables', solution: 'Data Solutions' }, { category: 'Nails', solution: 'Hardware' }, { category: 'Locks', solution: 'Hardware' }, { category: 'Screws', solution: 'Hardware' }, { category: 'Cabinets', solution: 'Cabinet Solutions' }, { category: 'Swing Frames', solution: 'Cabinet Solutions' }, { category: 'Racks', solution: 'Cabinet Solutions' }, { category: 'Fire Cables', solution: 'Fire Solutions' }, ];
var solutions = categories.reduce((acc, curr) => {
let item = acc.find(item => item.name === curr.solution);
if (item) {
item.categories.push({
"id": item.categories.length,
"name": curr.category,
"slug": curr.category.toLowerCase().replace(' ', '-')
});
} else {
acc.push({
"id": acc.length,
"name": curr.solution,
"categories": [{
"id": 0,
"name": curr.category,
"slug": curr.category.toLowerCase().replace(' ', '-')
}]
});
}
return acc;
}, []);
console.log(solutions);
Upvotes: 3
Reputation: 6015
The below code creates an intermediate array map of solutions to category and then uses it to generate output of the required format by using the keys and values of the mapped Object.
const categories = [
{ category: 'Patch Leads', solution: 'Data Solutions' },
{ category: 'Cables', solution: 'Data Solutions' },
{ category: 'Nails', solution: 'Hardware' },
{ category: 'Locks', solution: 'Hardware' },
{ category: 'Screws', solution: 'Hardware' },
{ category: 'Cabinets', solution: 'Cabinet Solutions' },
{ category: 'Swing Frames', solution: 'Cabinet Solutions' },
{ category: 'Racks', solution: 'Cabinet Solutions' },
{ category: 'Fire Cables', solution: 'Fire Solutions' },
];
const solutionMap = categories.reduce((acc,item) => {
if(!acc[item.solution])
acc[item.solution] = [];
acc[item.solution].push(item.category);
return acc;
},{});
const solutions = Object.entries(solutionMap).map(([key,val],id) => ({
id,
name: key,
categories: val.map((category,idx) => ({id: idx, name: category, slug: category.toLowerCase().replace(' ','-')}))
}));
console.log(solutions);
Upvotes: 0