I ended up developing a more generic function, presented below.
function group_by (lista, coluna) {
var colunas = {};
var resultado = [];
lista.forEach(function (item) {
var reg = {};
colunas[item[coluna]] = colunas[item[coluna]] || [];
for (var i in item)
if (i != coluna)
reg[i] = item[i];
colunas[item[coluna]].push(reg);
});
for (var i in colunas)
resultado.push({key: i, values: colunas[i]});
return resultado;
}
She naturally does the group by
on only one level, returning a list of objects with the attributes key
, with the value of the selected column, and values
, with the remaining values.
Consider the entry below:
[
{
"disciplina": "Portugues",
"periodo": "1º Bimestre",
"tipo": "1ª avaliacao",
"valor": 9.5
},
{
"disciplina": "Matematica",
"periodo": "1º Bimestre",
"tipo": "1ª avaliacao",
"valor": 9.5
},
{
"disciplina": "Matematica",
"periodo": "1º Bimestre",
"tipo": "Trabalho",
"valor": 9.5
},
{
"disciplina": "Matematica",
"periodo": "2º Bimestre",
"tipo": "1ª avaliacao",
"valor": 6.3
}
]
Executing the group_by
over the column periodo
, group_by(lista, "periodo")
, we would have the following output:
[
{
"key":"1º Bimestre",
"values":[
{
"disciplina":"Portugues",
"tipo":"1ª avaliacao",
"valor":9.5
},
{
"disciplina":"Matematica",
"tipo":"1ª avaliacao",
"valor":9.5
},
{
"disciplina":"Matematica",
"tipo":"Trabalho",
"valor":9.5
}
]
},
{
"key":"2º Bimestre",
"values":[
{
"disciplina":"Matematica",
"tipo":"1ª avaliacao",
"valor":6.3
}
]
}
]
To get a group by
second-degree, so to speak, it is sufficient to perform the function again on the present list in values
, in the desired column. For example, to do the group by
over the column disciplina
and get the expected result, we do:
group_by(lista, "periodo").map(function (item) {
return {key: item.key, values: group_by(item.values, "disciplina")};
});
Producing the following result:
[
{
"key":"1º Bimestre",
"values":[
{
"key":"Portugues",
"values":[
{
"tipo":"1ª avaliacao",
"valor":9.5
}
]
},
{
"key":"Matematica",
"values":[
{
"tipo":"1ª avaliacao",
"valor":9.5
},
{
"tipo":"Trabalho",
"valor":9.5
}
]
}
]
},
{
"key":"2º Bimestre",
"values":[
{
"key":"Matematica",
"values":[
{
"tipo":"1ª avaliacao",
"valor":6.3
}
]
}
]
}
]
How about testing for a larger input? Let’s assume further that we want to separate the records according to the tipo
, to separate notes from proofs, lists, etc.
group_by(lista, "periodo").map(function (item) {
return {key: item.key, values: group_by(item.values, "disciplina").map(function(item){
return {key: item.key, values: group_by(item.values, "tipo")}
})};
})
The way out:
[
{
"key":"1º Bimestre",
"values":[
{
"key":"Portugues",
"values":[
{
"key":"Prova",
"values":[
{
"valor":9.5
}
]
},
{
"key":"Lista",
"values":[
{
"valor":8.8
},
{
"valor":5.2
}
]
}
]
},
{
"key":"Matematica",
"values":[
{
"key":"Prova",
"values":[
{
"valor":9.5
}
]
}
]
}
]
},
{
"key":"2º Bimestre",
"values":[
{
"key":"Biologia",
"values":[
{
"key":"Prova",
"values":[
{
"valor":9.5
}
]
},
{
"key":"Lista",
"values":[
{
"valor":10
}
]
}
]
}
]
},
{
"key":"3º Bimestre",
"values":[
{
"key":"Geografia",
"values":[
{
"key":"Lista",
"values":[
{
"valor":9.5
},
{
"valor":9.9
}
]
}
]
}
]
}
]
This solution served perfectly! Excellent! Thank you very much Anderson. Hug.
– David Coelho
Perhaps it is still possible to improve it using recursiveness to call something like
group_by(lista, ["periodo", "disciplina"])
, but it was late and I couldn’t think anymore.– Woss
Friend, how do I convert the result of this code into a table?
– Italo Rodrigo
@Italorodrigo just do the
for
usvalues
and build the table.– Woss