0

As a react apprentice, I'm having a hard time mapping data into a new object grouping by it states, I´ve tried example_1 and example_2 with no success, also saw a lot of simple mapping questions that doesn't apply into my case.

My App.js:

    import "./styles.css";

    export default function App() {
      
      const data = [
          {
            "id": 1,
            "name": "Chris",
            "state": "MA",
            "stateId": 1
          },
          {
            "id": 2,
            "name": "Jenna",
            "state": "MA",
            "stateId": 1
          },
          {
            "id": 3,
            "name": "Pat",
            "state": "RI",
            "stateId": 2
          },
          {
            "id": 4,
            "name": "Dan",
            "state": "RI",
            "stateId": 2
          }
        ];
      const newdata = data.map((comp) => ({
        stateId: comp.stateId,
        state: comp.state,
        person: [{ id: comp.id, name: comp.name }]
      }));
      console.log(newdata)

      return (
        <div className="App">      
          <h2>
            <h1>test</h1>
          </h2>
        </div>
      );
    }

I would like to have something like this:

      [
        {
          "stateId": 1,
          "state": "MA",
          "person": [
            {
              "id": "1",
              "name": "chris"
            },
            {
              "id": "2",
              "name": "Jenna"
            }
          ]
        },
        {
          "stateId": 2,
          "state": "RI",
          "person": [
            {
              "id": "3",
              "name": "Pat"
            },
            {
              "id": "4",
              "name": "Dan"
            }
          ]
        }
      ]
pilchard
  • 12,414
  • 5
  • 11
  • 23
Marisco
  • 125
  • 1
  • 3
  • 16
  • 1
    You can't use `map()` for a group by because it will always return an array of the same length as the array it is called on. You will need to use a `for...` loop or `reduce()` as per the duplicate. – pilchard Feb 17 '23 at 15:11
  • 1
    This is a clear duplicate and should be closed as such, but here is a quick [jsfiddle](https://jsfiddle.net/z15phxan/2/) to help you on your way. – pilchard Feb 17 '23 at 15:28

1 Answers1

0

You can use reduce for hard mapping:

const result = data.reduce((acc, value, index, array) => {
  const result = [...acc];
  // Find index to know is state exist in acc and what index state has
  const stateIndex = acc.findIndex((v) => v.stateId === value.stateId);

  // Person object to use in different conditions
  const person = {
    id: value.id,
    name: value.name
  };

  // If state dont exist - push to result array
  if (stateIndex < 0) {
    result.push({
      stateId: value.stateId,
      state: value.state,
      person: [
        {
          id: value.id,
          name: value.name
        }
      ]
    });
  
  // If state exist - add person
  } else {
    result[stateIndex] = {
      ...result[stateIndex],
      person: result[stateIndex]?.person
        ? [...result[stateIndex].person, person]
        : [person]
    };
  }

  return result;
}, []);

Looks like it works https://codesandbox.io/s/fervent-varahamihira-gfymx8?file=/src/index.js

rycha
  • 679
  • 2
  • 9