У меня есть массив с объектами что-то вроде этого:

arr = [
  {name: 'Igor', id: 1,....},
  {name: 'Anton', id: 1,.... },
  {name: 'Igor', id: 2,.... },
  {name: 'Peter', id: 2,.... },
  {name: 'Igor', id: 2,.... }
]

Мне нужно получить новый массив, как:

arrId = [
  { id: 1, names: 'Igor, Anton' },
  { id: 2, names: 'Igor, Peter' }
]

Не могу придумать хорошего решения

0
Igor Kim 18 Дек 2015 в 11:11

3 ответа

Лучший ответ

В этом примере я использую map и reduce,

function rearrange(arr) {

  // use `reduce` to build an object using the ids as keys
  // this allows us to place all the names with the same id together
  // note we pass in an empty object to act as our initial p argument.
  var out = arr.reduce(function (p, c) {
    var key = c.id, name = c.name;

    // if the key doesn't exist create it and set its value
    // to an empty array
    p[key] = p[key] || [];

    // add the name to the array if it doesn't already exist
    if (p[key].indexOf(name) === -1) p[key].push(name);
    return p;
  }, {});

  // use `map` to return an array of objects
  return Object.keys(out).map(function (el) {

    // make sure we use an integer for the id, and
    // join the array to get the appropriate output
    return { id: +el, names: out[el].join(', ') };
  });

}

rearrange(arr);

ДЕМО

ВЫХОД

[
  {
    "id": 1,
    "names": "Igor, Anton"
  },
  {
    "id": 2,
    "names": "Igor, Peter"
  }
]
4
Andy 18 Дек 2015 в 08:43
var arrId = [];
var arrKey = {};
for( var counter = 0; counter < arr.length; counter++)
{ 
  var arrObj = arr[ counter ];
  if ( !arrKey[  arrObj[ "id" ] ] )
  {
    arrKey[  arrObj[ "id" ] ] = [];
  }
  arrKey[  arrObj[ "id" ] ].push( arrObj[ "name" ] );
}
for ( var id in arrKey )
{
  arrId.push( [ "id": id, names : arrKey[ id ].join( "," ) ] );
}
console.log(arrId );
0
gurvinder372 18 Дек 2015 в 08:16

Вы можете использовать функцию уменьшить

arr = [
  {name: 'Igor', id: 1},
  {name: 'Anton', id: 1 },
  {name: 'Igor', id: 2 },
  {name: 'Peter', id: 2 },
  {name: 'Igor', id: 2 }
]

//first group needed fields from items by id
var result = arr.reduce(function(acc,cur){
  if(!acc.map[cur.id]) {
    acc.map[cur.id] = {id:cur.id, names:{}};
    acc.result.push(acc.map[cur.id]);
    }
  acc.map[cur.id].names[cur.name]=true;
  return acc;
},{map:{},result:[]})
//do addtional transfrom from map object with names, to string separated by comma
.result.map(function(el){
  return {id:el.id, names: Object.keys(el.names).join(', ')};
});
console.log(result);
document.body.innerHTML = JSON.stringify(result,null, 2);
1
Grundy 18 Дек 2015 в 08:28