Group repeated records into an array in javascript

Asked

Viewed 2,088 times

0

I have a JS array with only two attributes, a state name and a city name. Example:

var variavel = [{estado: 'São Paulo', cidade: 'Campinas'},
                {estado: 'São Paulo', cidade: 'Santos'},
                {estado: 'São Paulo', cidade: 'Sorocaba'},
                {estado: 'Bahia', cidade: 'Salvador'},
                {estado: 'Bahia', cidade: 'Ilhéus'},
                {estado: 'Rio Grande do Sul', cidade: 'Porto Alegre'}];

But now I would like to group cities by state, eliminating repeated information, thus staying:

var variavel = [{estado: 'São Paulo', cidades: [{nome: 'Campinas'}, {nome: 'Santos'}, {nome: 'Sorocaba'}]},
                {estado: 'Bahia', cidades: [{nome: 'Salvador'}, {nome: 'Ilhéus'}]},
                {estado: 'Rio Grande do Sul', cidades: [{nome: 'Porto Alegre'}]}];

How best to achieve this result?

2 answers

1

I would approach the problem like this:

  • a single object with a key to each city
  • iterate the initial array to fill this object
  • after having an object as described then generate an array again if necessary. This last step would be expendable, depends on the use of this object.

Example:

const variavel = [{ estado: 'São Paulo', cidade: 'Campinas' }, { estado: 'São Paulo', cidade: 'Santos' }, { estado: 'São Paulo', cidade: 'Sorocaba' }, { estado: 'Bahia', cidade: 'Salvador' }, { estado: 'Bahia', cidade: 'Ilhéus' }, { estado: 'Rio Grande do Sul', cidade: 'Porto Alegre' } ];

const estados = variavel.reduce((obj, {estado, cidade}) => {
  if (!obj[estado]) obj[estado] = [];
  obj[estado].push(cidade);
  return obj;
}, {});

console.log(JSON.stringify(estados)); // eu usaria este objeto

const outraVariante = Object.keys(estados).map(estado => {
  return {
    estado,
    cidades: estados[estado]
  };
});
console.log(JSON.stringify(outraVariante)); // como pedes na pergunta seria assim

0

This algorithm is not the best in performance issues, but brings the expected result.

For repeated states not to be added separately, it is checked if there is no state with the same name, if any, to add the city of the repeated state to the object containing the existing state:

var variavel = [
    {estado: 'São Paulo', cidade: 'Campinas'}, 
    {estado: 'São Paulo', cidade: 'Santos'}, 
    {estado: 'São Paulo', cidade: 'Sorocaba'}, 
    {estado: 'Bahia', cidade: 'Salvador'}, 
    {estado: 'Bahia', cidade: 'Ilhéus'}, 
    {estado: 'Rio Grande do Sul', cidade: 'Porto Alegre'}
    ];
var saida = [];

for (var i = 0; i < variavel.length; i++) {
    var cidadeIgual = false;
    for (var j = 0; j < i; j++) {
        if (saida[j] && variavel[i].estado == saida[j].estado) {
            saida[j].cidades.push({
                nome: variavel[i].cidade
            })
            cidadeIgual = true;
            break;
        }
    }
    
    if (!cidadeIgual) {
        saida.push({
            estado: variavel[i].estado,
            cidades: [{
                nome: variavel[i].cidade
            }]
        })
    }
}

console.log(saida)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.