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
forusvaluesand build the table.– Woss