Dynamic Grouping of JSON Data

7

I have been trying for some days to dynamically group JSON data, but without success, it is a matter of logic rather than programming itself.

Given an array of objects (Users), group them according to their attributes (name, age, etc.).

The grouping must be dynamic and the result will be displayed according to the chosen attributes.

JSON:

var lUsuarios = [{
    "NOME":"ANTONIO CARLOS CURY",
    "IDADE": 28,
    "SEXO": "MASCULINO",
    "ADMINISTRADOR": true
},{
    "NOME":"CESAR SIQUEIRA JUNIOR",
    "IDADE": 23,
    "SEXO": "MASCULINO",
    "ADMINISTRADOR": false
},{
    "NOME":"ANDREI SALVADOR",
    "IDADE": 18,
    "SEXO": "MASCULINO",
    "ADMINISTRADOR": true
},{
    "NOME":"SERGIO MORO",
    "IDADE": 35,
    "SEXO": "MASCULINO",
    "ADMINISTRADOR": false
},{
    "NOME":"MARIA DA SILVA",
    "IDADE": 17,
    "SEXO": "FEMININO",
    "ADMINISTRADOR": true,
},{
    "NOME":"JOANA FINA",
    "IDADE": 19,
    "SEXO": "FEMININO",
    "ADMINISTRADOR": false
},{
    "NOME":"ELIANE DA SILVA",
    "IDADE": 21,
    "SEXO": "FEMININO",
    "ADMINISTRADOR": true,
},{
    "NOME":"MARIA BONITA",
    "IDADE": 47,
    "SEXO": "FEMININO",
    "ADMINISTRADOR": false
}]</code>

Grouping function:

function AgruparJSON(colunas){
    //Throw new Exception("Não sei o que vai aqui");
}

Method call:

The great difficulty is in the compound groupings, where they will be grouped by two or more attributes of the user list (JSON).

$(function(){

    //JSON de dados dos usuários
    var lUsuarios = JSON.parse('[{...}]');

    var lUsuariosSexoAdministrador = lUsuarios.AgruparJSON("SEXO", "ADMINISTRADOR");    
    console.log(lUsuariosSexoAdministrador);

    //Resultado esperado para console.log(lUsuariosSexoAdministrador);
    [{"MASCULINO":
        [{ "true" : [{
                        "NOME":"ANTONIO CARLOS CURY",
                        "IDADE": 28,
                        "SEXO": "MASCULINO",
                        "ADMINISTRADOR": true
                    },{
                        "NOME":"ANDREI SALVADOR",
                        "IDADE": 18,
                        "SEXO": "MASCULINO",
                        "ADMINISTRADOR": true}]
        },{ "false": [{
                        "NOME":"CESAR SIQUEIRA JUNIOR",
                        "IDADE": 23,
                        "SEXO": "MASCULINO",
                        "ADMINISTRADOR": false
                    },{
                        "NOME":"SERGIO MORO",
                        "IDADE": 35,
                        "SEXO": "MASCULINO",
                        "ADMINISTRADOR": false
                    }]
        }]
    },{"FEMININO":
        [{ "true" : [{
                        "NOME":"MARIA DA SILVA",
                        "IDADE": 17,
                        "SEXO": "FEMININO",
                        "ADMINISTRADOR": true
                    },{
                        "NOME":"ELIANE DA SILVA",
                        "IDADE": 21,
                        "SEXO": "FEMININO",
                        "ADMINISTRADOR": true
                    }]
        },{ "false": [{
                        "NOME":"MARIA BONITA",
                        "IDADE": 47,
                        "SEXO": "FEMININO",
                        "ADMINISTRADOR": false
                    },{
                        "NOME":"JOANA FINA",
                        "IDADE": 19,
                        "SEXO": "FEMININO",
                        "ADMINISTRADOR": false
                    }]
        }]
    }]; 
});
    
asked by anonymous 19.10.2017 / 19:46

2 answers

1

Here is a simple algorithm that groups your data based on an arbitrary amount of attributes:

var lUsuarios=[{"NOME":"ANTONIO CARLOS CURY","IDADE":28,"SEXO":"MASCULINO","ADMINISTRADOR":true},{"NOME":"CESAR SIQUEIRA JUNIOR","IDADE":23,"SEXO":"MASCULINO","ADMINISTRADOR":false},{"NOME":"ANDREI SALVADOR","IDADE":18,"SEXO":"MASCULINO","ADMINISTRADOR":true},{"NOME":"SERGIO MORO","IDADE":35,"SEXO":"MASCULINO","ADMINISTRADOR":false},{"NOME":"MARIA DA SILVA","IDADE":17,"SEXO":"FEMININO","ADMINISTRADOR":true},{"NOME":"JOANA FINA","IDADE":19,"SEXO":"FEMININO","ADMINISTRADOR":false},{"NOME":"ELIANE DA SILVA","IDADE":21,"SEXO":"FEMININO","ADMINISTRADOR":true},{"NOME":"MARIA BONITA","IDADE":47,"SEXO":"FEMININO","ADMINISTRADOR":false}];

// complexidade aproximada de O(2N * C), onde:
// N = length de "lUsuarios"
// C = length de "colunas"
function AgruparJSON(colunas){
	var colsObjData = {};

	// 1. agrupamos por categorias em chaves que são a concatenação dos valores
	// das colunas desejas, something like "MASCULINO;true" ou "FEMININO;false"
	lUsuarios.forEach(function(userObj) {
		var key = colunas.reduce(function(a, b) {
			return (a ? a + ';' : a) + userObj[b];
		}, '');
		if (!(key in colsObjData)) {
			colsObjData[key] = [];
		}
		colsObjData[key].push(userObj);
	});

	// 2. já possuimos os agrupamentos, agora é apenas uma questão de transformar eles 
	// na estrutura desejada
	var finalData = {};
	for (var key in colsObjData) {
		var data = finalData;
		var splited = key.split(';');
		splited.forEach(function(col, index) {
			if (!(col in data)) {
				data[col] = {}
			}
			if (index === splited.length - 1) {
				data[col] = colsObjData[key];
			}
			else {
				data = data[col];
			}
		});
	}
	return finalData;
}

var result = AgruparJSON(["SEXO", "ADMINISTRADOR"]);
document.writeln(JSON.stringify(result));

Note:

Pretty print of the result:

{
  "MASCULINO": {
    "true": [
        {
            "NOME": "ANTONIO CARLOS CURY",
            "IDADE": 28,
            "SEXO": "MASCULINO",
            "ADMINISTRADOR": true
        },
        {
            "NOME": "ANDREI SALVADOR",
            "IDADE": 18,
            "SEXO": "MASCULINO",
            "ADMINISTRADOR": true
        }
    ],
    "false": [
        {
            "NOME": "CESAR SIQUEIRA JUNIOR",
            "IDADE": 23,
            "SEXO": "MASCULINO",
            "ADMINISTRADOR": false
        },
        {
            "NOME": "SERGIO MORO",
            "IDADE": 35,
            "SEXO": "MASCULINO",
            "ADMINISTRADOR": false
        }
    ]
  },
  "FEMININO": {
    "true": [
        {
            "NOME": "MARIA DA SILVA",
            "IDADE": 17,
            "SEXO": "FEMININO",
            "ADMINISTRADOR": true
        },
        {
            "NOME": "ELIANE DA SILVA",
            "IDADE": 21,
            "SEXO": "FEMININO",
            "ADMINISTRADOR": true
        }
    ],
    "false": [
        {
            "NOME": "JOANA FINA",
            "IDADE": 19,
            "SEXO": "FEMININO",
            "ADMINISTRADOR": false
        },
        {
            "NOME": "MARIA BONITA",
            "IDADE": 47,
            "SEXO": "FEMININO",
            "ADMINISTRADOR": false
        }
    ]
  }
}
    
19.10.2017 / 23:04
-1

I know that I've been answering for some time but I found a way to do what I wanted, just to update here

function agruparJSON(coluna, valor) {
    var array = []
    for(i=0;i<lUsuarios.length;i++) {
        if (lUsuarios[i][coluna] == valor) {
            array.push(lUsuarios[i])
        }
    }
    return array
}

agruparJSON('SEXO', 'MASCULINO')
    
19.10.2017 / 21:00