Paul VI
Paul VI

Reputation: 583

React: How to render a list of items grouped by category (using .map)

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

Answers (1)

cmgchess
cmgchess

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}`)
);
});

Edit bold-saha-gxzh9

Upvotes: 4

Related Questions