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"
            }
          ]
        }
      ]
2
  • 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. Commented Feb 17, 2023 at 15:11
  • 1
    This is a clear duplicate and should be closed as such, but here is a quick jsfiddle to help you on your way. Commented Feb 17, 2023 at 15:28

1 Answer 1

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

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.