Search code examples
javascriptreactjslodash

how to group array of objects by value in reactjs


Considering the array

const a1 = [
  { id: 1, nome: 'Ruan', status: { id: 1, posicao: 'goleiro' } },
  { id: 2, nome: 'Gleison', status: { id: 2, posicao: 'zagueiro' } },
  { id: 3, nome: 'Geraldo', status: { id: 2, posicao: 'zagueiro' } },
  { id: 4, nome: 'Heleno', status: { id: 3, posicao: 'atacante' } },
  { id: 5, nome: 'Djandel', status: { id: 3, posicao: 'atacante' } }
]

I've tried using reduce, but without success, I tried the code below

var groupBy = function(xs, key) {
  return xs.reduce(function(rv, x) {
    (rv[x[key]] = rv[x[key]] || []).push(x);
    return rv;
  }, {});
  groupBy(a1, 'status')
};

I also tried with lodash

_.groupBy(a1, 'status');

I hope that 3 different arrays will return, one with the goleiros, another with the zagueiros and another with the atacantes

And how to display the information separately in the react view?


Solution

  • You can use group by like this:

    _.groupBy(a1, "status.posicao")
    

    To specify that you need to group them by status.posicao, take a look at this sandbox it will return an object with the three groups.

    https://codesandbox.io/s/strange-sanne-icdy3?file=/src/index.js

    Edit:

    If you want to build your own function without lodash and assuming you know the shape of the object, you can build something like this (I'm using your array example):

    const a1 = [
      { id: 1, nome: "Ruan", status: { id: 1, posicao: "goleiro" } },
      { id: 2, nome: "Gleison", status: { id: 2, posicao: "zagueiro" } },
      { id: 3, nome: "Geraldo", status: { id: 2, posicao: "zagueiro" } },
      { id: 4, nome: "Heleno", status: { id: 3, posicao: "atacante" } },
      { id: 5, nome: "Djandel", status: { id: 3, posicao: "atacante" } },
    ];
    
    function groupBy(items) {
      return items.reduce((acc, curr) => {
        if (curr.status?.posicao) {
          const { posicao } = curr.status;
          const currentItems = acc[posicao];
      
          return { 
            ...acc,
            [posicao]: currentItems ? [...currentItems, curr] : [curr]
          };
        }
        return acc;
      }, {});
    }
    
    console.log(groupBy(a1))