How to group an array of objects in javascript (Angular)

2

How to read an array of objects and return only objects that contain the same value in multiple attributes? I made this object array as an example.

var arrayDeObjetos = [
  {"dia":1 , "desc":"Nigth","mes":1},
  {"dia":1 , "Descricao":"Brilha","mes":1},
  {"dia":2 , "desc":"Urna","mes":2},
  {"dia":3 , "Descricao":"Covas","mes":1},
  {"dia":2 , "desc":"Mario Corvas","mes":1},
  {"dia":4 , "Desc":"Estrelas","mes":2}
];

In this Array I have several objects I wanted to group all and a new array that contains an object with all containing dia = 1 and mes = 1 another object that contains all with dia = 2 and mes = 2 The end result has to be something like

var resultado = [
  [
    {"dia":1,"mes":1,"desc":"descricao AQI"},
    {"dia":1,"mes":1,"desc":"Outra desc"}
  ],
  [
    {"dia":2,"mes":2,"desc":"outro mes"},
    {"dia":1,"mes":1,"desc":"outra coisa"}
  ]];
    
asked by anonymous 22.11.2016 / 17:35

4 answers

1

If the object array is too long, you can separate an array of non-duplicate objects by mapping days and months and then filter based on what has been discovered.

var arrayDeObjetos = [
  {"dia":1 , "desc":"Nigth","mes":1},
  {"dia":1 , "Descricao":"Brilha","mes":1},
  {"dia":2 , "desc":"Urna","mes":2},
  {"dia":3 , "Descricao":"Covas","mes":1},
  {"dia":2 , "desc":"Mario Corvas","mes":1},
  {"dia":4 , "Desc":"Estrelas","mes":2}
];

Will become objetosASeparar :

objetosASeparar = [
  {dia: 1, mes: 1},
  {dia: 2, mes: 2}
]

So if there is day 3 and month 3, day 4 and month 4 onwards, all will be filtered in a new object.

var arrayDeObjetos = [
  {"dia":1 , "desc":"Nigth","mes":1},
  {"dia":1 , "Descricao":"Brilha","mes":1},
  {"dia":2 , "desc":"Urna","mes":2},
  {"dia":3 , "Descricao":"Covas","mes":1},
  {"dia":2 , "desc":"Mario Corvas","mes":1},
  {"dia":4 , "Desc":"Estrelas","mes":2}
];

// obter um array de objetos com dia e mes não duplicados
var objetosASeparar = [];
arrayDeObjetos.filter(item => item.dia == item.mes).map(function(item){
  if(item.dia == item.mes){
    return {
      dia: item.dia,
      mes: item.mes
      }
  }
}).forEach(function(a){
  if (objetosASeparar.length == 0) objetosASeparar.push(a);
  objetosASeparar.forEach(function(b){
    if (b.dia !== a.dia && b.mes !== a.mes)
      objetosASeparar.push(a);
  });
});

// filtrados com base nos objetos descobertos
var novoObjeto = {};
objetosASeparar.forEach(function(a,i){
    novoObjeto[i] = arrayDeObjetos.filter(b => a.dia == b.dia && a.mes == b.mes);
});

console.log(novoObjeto);
    
22.11.2016 / 18:38
1

One way is to use Javascript Filter to find only the values you need and insert them into a new array using push , see the example below:

var arrayDeObjetos = [
  {"dia":1 , "desc":"Nigth","mes":1},
  {"dia":1 , "Descricao":"Brilha","mes":1},
  {"dia":2 , "desc":"Urna","mes":2},
  {"dia":3 , "Descricao":"Covas","mes":1},
  {"dia":2 , "desc":"Mario Corvas","mes":1},
  {"dia":4 , "Desc":"Estrelas","mes":2}
];

var novoArray = [];

novoArray.push(filtrarArray(arrayDeObjetos, 1, 1));
novoArray.push(filtrarArray(arrayDeObjetos, 2, 2));

console.log(novoArray);

function filtrarArray(array, dia, mes) {
  return array.filter(function(val) {
    return val.dia === dia && val.mes === mes;  
  });
}
    
22.11.2016 / 17:48
0

Do

var objetos = [
   {"dia":1 , "desc":"Nigth","mes":1},
   {"dia":1 , "Descricao":"Brilha","mes":1},
   {"dia":1 , "desc":"Nigth","mes":1},
   {"dia":2 , "desc":"Urna","mes":2}
]

var meuNovoArray = [];

angular.forEach(objetos, function(objeto)){
     if(objeto.dia === 1){
         menuNovoArray.push(objeto) //adiciona o obj nesse seu novo array
     }
}

Then just give console.log (myNewArray) that will work.

    
22.11.2016 / 19:13
0

This type of operation is called map reduce, in the javascript all array has the operation reduces for these cases. Here are 2 examples of how to use it in your case.

Using Object:

Object.values([
    {"dia":1 , "desc":"Nigth","mes":1},
    {"dia":1 , "Descricao":"Brilha","mes":1},
    {"dia":2 , "desc":"Urna","mes":2},
    {"dia":3 , "Descricao":"Covas","mes":1},
    {"dia":2 , "desc":"Mario Corvas","mes":1},
    {"dia":4 , "Desc":"Estrelas","mes":2}
  ].reduce(function(prev, item) {
    var key = item.dia * 100 + item.mes;
    prev[key] = prev[key] || [];
    prev[key].push(item);
    return prev;
  }, {})
);

Using Array:

[
  {"dia":1 , "desc":"Nigth","mes":1},
  {"dia":1 , "Descricao":"Brilha","mes":1},
  {"dia":2 , "desc":"Urna","mes":2},
  {"dia":3 , "Descricao":"Covas","mes":1},
  {"dia":2 , "desc":"Mario Corvas","mes":1},
  {"dia":4 , "Desc":"Estrelas","mes":2}
]
.reduce(function(prev, current) {
    var index = prev.findIndex(function(j) { return j.dia == current.dia && j.mes == current.mes});
    if (index < 0) {
        index = prev.length;
        prev.push({
            dia: current.dia,
            mes: current.mes,
            lista: []
        });
    }
    prev[index].lista.push(current);
    return prev;
}, [])
.map(function(item){
    return item.lista;
});

Although more complex the method using array must be more efficient than the method using object.

Note Do not index the array day and month, eg array [month * 100 + day], because in the javascript language it will create all positions in the array until it reaches the value reported.

    
28.11.2017 / 13:57