Concatenate id by description into an array in javascript

Asked

Viewed 459 times

1

I have an array in js with only an id and a description, example:

var variavel = [{id: 1, descrição: 'Brasil'},
             {id: 2, descrição: 'Brasil'},
             {id: 3, descrição: 'Chile'},
             {id: 4, descrição: 'Chile'},
             {id: 5, descrição: 'Chile'},
             {id: 6, descrição: 'Argentina'}];

But I would like to concatenate the id and leave only the description, basically this way:

var variavel = [{id: '1,2', descrição: 'Brasil'},
                     {id: '3,4,5', descrição: 'Chile'},
                     {id: '6', descrição: 'Argentina'}];

How can I do that? One loop/for would solve?

NOTE: I don’t use/I can use Jquery in this project

5 answers

2

Two loops will do. The first traverses the variable with the repeated fields, inside makes a new loop to check if that object already exists in the new variable, if it exists, updates the id, if not, adds

const variavel = [
  {id: 1, descrição: 'Brasil'},
  {id: 2, descrição: 'Brasil'},
  {id: 3, descrição: 'Chile'},
  {id: 4, descrição: 'Chile'},
  {id: 5, descrição: 'Chile'},
  {id: 6, descrição: 'Argentina'}
];

const novaVariavel = [];

for (const objeto of variavel) {
  let existe = false;

  for (let i = 0; i < novaVariavel.length; i++) {
    if (objeto['descrição'] === novaVariavel[i]['descrição']) {
      novaVariavel[i].id += `,${objeto.id}`;
      existe = true;
    }
  }

  if (!existe) {
    novaVariavel.push(objeto);
  }
}

console.log(novaVariavel)

2


There are several ways to do this. I recommend using the Javascript method forEach to iterate over your array, and compose a new array. It would look something like this:

// Array com os valores indicados no enunciado.
var array = [
    {id: '1', descricao: 'Brasil'},
    {id: '2', descricao: 'Brasil'},
    {id: '3', descricao: 'Chile'},
    {id: '4', descricao: 'Chile'},
    {id: '5', descricao: 'Chile'},
    {id: '6', descricao: 'Argentina'}
];

// Novo Array que será populado de acordo com a lógica apresentada.
var novoArray = [];

// Aqui usamos o método do Javascript, forEach, presente nos arrays para percorrer os objetos
array.forEach(function(item){
    // Aqui vamos verificar através do método map, se a descrição já foi salva dentro do novoArray.
    var indice = novoArray.map(function(e) { 
        return e.descricao; 
    }).indexOf(item.descricao);

    // Se achamos, vamos nesse índice localizado, e concatenamos o ID ao já existente
    // Se não, usamos o método push, para atribuir o novo item ao novoArray.
    if(indice >= 0) {
        novoArray[indice].id += ', ' + item.id;
    } else {
        novoArray.push(item);
    }
});

console.log(novoArray);

At the end of the variable novoArray will have the following value as requested:

[
  {
    "id": "1, 2",
    "descricao": "Brasil"
  },
  {
    "id": "3, 4, 5",
    "descricao": "Chile"
  },
  {
    "id": "6",
    "descricao": "Argentina"
  }
]

2

I will collaborate with an O(n) algorithm instead of O(n 2), using two non-nested loop repeats.


The first loop groups the id by country:

var grupos = {};
lista.forEach(function(obj) {
    grupos[obj.descricao] = grupos[obj.descricao] || [];
    grupos[obj.descricao].push(obj.id)
});

The content of grupo now is:

{
    "Brasil": [1, 2],
    "Chile": [3, 4, 5],
    "Argentina": [6]
}

In the second loop I just go through the previous object and populate the array with the desired data:

Object.keys(grupos).forEach(function(pais) {
    resultado.push({
        id: grupos[pais].join(','),
        descricao: pais
    });
});

Upshot:

[
    {
        "id": "1,2",
        "descricao": "Brasil"
    },
    {
        "id": "3,4,5",
        "descricao": "Chile"
    },
    {
        "id": "6",
        "descricao": "Argentina"
    }
]

Code working:

let lista = [
  {id: 1, descricao: 'Brasil'},
  {id: 2, descricao: 'Brasil'},
  {id: 3, descricao: 'Chile'},
  {id: 4, descricao: 'Chile'},
  {id: 5, descricao: 'Chile'},
  {id: 6, descricao: 'Argentina'}
];
 
let grupos = {};

lista.forEach(obj => {
  grupos[obj.descricao] = grupos[obj.descricao] || [];
  grupos[obj.descricao].push(obj.id)
});

let resultado = [];

Object.keys(grupos).forEach(pais => {
  resultado.push({
    id: grupos[pais].join(','),
    descricao: pais
  })
});

console.log(resultado)

1

I believe you need something in that direction (running):

var groups = {};
for (var i = 0; i < variavel.length; i++) {
    var groupName = variavel[i].descrição;
    if (!groups[groupName]) {
        groups[groupName] = [];
    }
    groups[groupName].push(variavel[i].id);
}
    variavel = [];
    for (var groupName in groups) {
    variavel.push({descrição: groupName, id: groups[groupName]});
}

I hope I’ve helped.
Hugs,

1

Among so many answers, follow one more option:

var lista = [{id: 1, descrição: 'Brasil'},
             {id: 2, descrição: 'Brasil'},
             {id: 3, descrição: 'Chile'},
             {id: 4, descrição: 'Chile'},
             {id: 5, descrição: 'Chile'},
             {id: 6, descrição: 'Argentina'}];

    var result = [...lista.reduce((item, {id,descrição}) => {
      if (!item.has(descrição)) 
        item.set(descrição, {id,descrição});
      
      item.get(descrição).id = item.get(descrição).id == id ? String(id) : item.get(descrição).id + ',' + id;
      return item;
    }, new Map()).values()];

    console.log(result);

Browser other questions tagged

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