Reputation: 583
I have an array (myArray), stored like so (in firebase):
[
{
"id": "1",
"Category": "Hardware",
"Name": "Xtreme"
},
{
"id": "123",
"Category": "Software",
"Name": "Obsolete"
},
{
"id": "12345",
"Category": "Software",
"Name": "V1"
},
{
"id": "1234567",
"Category": "Hardware",
"Name": "CPU"
}
]
I am using the following code:
const sorterAR = [];
myArray.forEach((item) => {
let cat = sorterAR.find(
(cat) => cat.id === item.id
);
if (!cat) {
cat = {
id: item.id,
Category: item.Category,
items: [],
};
sorterAR.push(cat);
}
cat.items.push(item);
});
And then displaying like so:
<div className="App">
{sorterAR.map((cat) => (
<>
<div>
<b>{cat.Category}</b>
</div>
<ul>
{cat.items.map((item) => (
<li>{item.Name}</li>
))}
</ul>
</>
))}
</div>
This works in that it produces an output like:
**Hardware**
Xtreme
**Hardware**
CPU
**Software**
Obsolete
**Software**
V1
How do I alter this to produce the following output:
**Hardware**
Xtreme
CPU
**Software**
Obsolete
V1
So that it displays the category name and then all the items in that category, and then moves to the next one and so forth?
Upvotes: 1
Views: 2717
Reputation: 10297
I assumed that order doesn't matter if Hardware or Software should come first.
First I categorized the array into an object of Category objects using Array.prototype.reduce().
From the resultant object you can build the JSX
var data1 = [
{
id: '1',
Category: 'Hardware',
Name: 'Xtreme',
},
{
id: '123',
Category: 'Software',
Name: 'Obsolete',
},
{
id: '12345',
Category: 'Software',
Name: 'V1',
},
{
id: '1234567',
Category: 'Hardware',
Name: 'CPU',
},
];
const categorizedData = data1.reduce((acc, curr) => {
const { id, Category, Name } = curr;
if (!acc[Category]) {
acc[Category] = {
items: [],
};
}
acc[Category].items.push(Name);
return acc;
}, {});
console.log(categorizedData);
Object.keys(categorizedData).map((key, index) => {
console.log(`Category: ${key}`);
categorizedData[key].items.map((item, index) =>
console.log(`Item ${index}: ${item}`)
);
});
Upvotes: 4