2

I've a requirement where the below array of objects should be converted to the result mentioned.

list = [{name : 'John', id : '1'}, {name : 'John', id : '2'}, {name : 'John', id : '3'}, {name : 'John', id : '4'}];

result to

list = [{name : 'John', id : '1, 2, 3, 4'}];

How can one do it?

Prateek Agarwal
  • 407
  • 1
  • 8
  • 20

3 Answers3

3

You could do it using a temporary object and Array#filter to filter out the duplicates and modify the original at the same time:

var list = [
        {name : 'John', id : '1'},
        {name : 'John', id : '2'},
        {name : 'John', id : '3'},
        {name : 'John', id : '4'}
    ],
    temp = {};

list = list.filter(function (o) {
    if (temp.hasOwnProperty(o.name)) {
        temp[o.name].id += ', ' + o.id;
        return false;
    }
    else {
        temp[o.name] = o;
        return true;
    }
});

document.body.textContent = JSON.stringify(list);
Andy E
  • 338,112
  • 86
  • 474
  • 445
1

You can group it in a single loop with the help of a temoprary object without mutating the original array.

var list = [{ name: 'John', id: '1' }, { name: 'John', id: '2' }, { name: 'John', id: '3' }, { name: 'John', id: '4' }],
    grouped = [];

list.forEach(function (a) {
    if (!this[a.name]) {
        this[a.name] = { data: { name: a.name }, array: [] };
        grouped.push(this[a.name].data);
    }
    this[a.name].array.push(a.id);
    this[a.name].data.id = this[a.name].array.join(', ');
}, Object.create(null));

document.write('<pre>' + JSON.stringify(grouped, 0, 4) + '</pre>');

A slightly compacter version

var list = [{ name: 'John', id: '1' }, { name: 'John', id: '2' }, { name: 'John', id: '3' }, { name: 'John', id: '4' }],
    grouped = [];

list.forEach(function (a) {
    if (!this[a.name]) {
        this[a.name] = { name: a.name, id: a.id };
        grouped.push(this[a.name]);
        return;
    }
    this[a.name].id += ', ' + a.id;
}, Object.create(null));

document.write('<pre>' + JSON.stringify(grouped, 0, 4) + '</pre>');
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
1

This is to solve your specific question rather than a more general solution

function consolidate(list){
    var names={};
    list.forEach(function(e){
        if (!names[e.name]) names[e.name]=[e.id];
        else names[e.name].push(e.id);
    });
    var rtn=[];
    Object.keys(names).forEach(function(n){
        rtn.push({name:n, id:names[n].join(', ')});
    });
    return rtn;
}

basically use an object to accumulate the data then remap back into an array.

Euan Smith
  • 2,102
  • 1
  • 16
  • 26