How to find values in an object in javascript?

0

I have a question, someone knows how to perform a search on a JSON object with the filter function of javascript but that the conditions are not established and are taken based on an arrangement for its manipulation, for example:

// Escuelas
var escuelas = [
  {id_escolares_pk: 1,escuela: "Gregorio",tipo: "Pública",id_nivel_fk: 1},
  {id_escolares_pk: 2,escuela: "Ignacio",tipo: "Privada",id_nivel_fk: 1},
  {id_escolares_pk: 3,escuela: "UTZ",tipo: "Pública",id_nivel_fk: 1}
];
'
'
// Arreglo con las condiciones a ejecutar
var comparaciones = ["id_nivel_fk == 1", "tipo == 'Privada'"];
'
'
// Ejecución de filter 
var encontrados = escuelas.filter(function(elemento) {
 return elemento.id_nivel_fk == 1 && elemento.tipo == "Privada" // ◄ Aquí se desea que aplique el arreglo comparaciones 
});
    
asked by Antonio 20.11.2018 в 18:40
source

3 answers

0

I leave you a small filter function, which you can adapt to what you need, try this:

function filter(list, compare){
var newList = [];
var countProp = compare.length;
var countMatch = 0;
var valComp;
var valList;

for(var iList in list) {
	valList = list[iList];
	countMatch = 0;
	for(var iComp in compare){
		valComp = compare[iComp];
		if(valList.hasOwnProperty(valComp.name)) {
			if(valComp.operator === "===" && valList[valComp.name] === valComp.value) countMatch++;
			else if(valComp.operator === "!==" && valList[valComp.name] !== valComp.value) countMatch++;
			else if(valComp.operator === "==" && valList[valComp.name] == valComp.value) countMatch++;
			else if(valComp.operator === "!=" && valList[valComp.name] != valComp.value) countMatch++;
			else if(valComp.operator === "<" && valList[valComp.name] < valComp.value) countMatch++;
			else if(valComp.operator === "<=" && valList[valComp.name] <= valComp.value) countMatch++;
			else if(valComp.operator === ">" && valList[valComp.name] > valComp.value) countMatch++;
			else if(valComp.operator === ">=" && valList[valComp.name] >= valComp.value) countMatch++;
		}
	}
	
	if(countMatch == countProp){
		newList.push(valList);
	}
}

return newList;
}

var escuelas = [
  {id_escolares_pk: 1,escuela: "Gregorio",tipo: "Pública",id_nivel_fk: 1},
  {id_escolares_pk: 2,escuela: "Ignacio",tipo: "Privada",id_nivel_fk: 1},
  {id_escolares_pk: 3,escuela: "UTZ",tipo: "Pública",id_nivel_fk: 1}
];

var comparaciones = [
{ name: "id_nivel_fk", value: 1, operator: "==" },
{ name: "tipo", value: "Pública", operator: "==" }
];

var encontrados1 = filter(escuelas, comparaciones);

var encontrados2 = filter(escuelas, [
{ name: "id_nivel_fk", value: 1, operator: "==" },
{ name: "tipo", value: "Privada", operator: "==" }
]);

var encontrados3 = filter([
  {modelo: "MCF", cantidad: 20},
  {modelo: "JKM", cantidad: 50},
  {modelo: "ERT", cantidad: 70},
],
[
{ name: "cantidad", value: 50, operator: ">=" }
]);

console.log("encontrados1: ", encontrados1);
console.log("encontrados2: ", encontrados2);
console.log("encontrados3: ", encontrados3);

The function is passed two arguments which are an array or list, the first contains the elements to be filtered and the second the values with which to filter or rules.

Each of the elements to be filtered is traversed and compared with each of the comparison rules, as long as their names agree and depending on the comparator that is passed to each rule.

For each match the variable countMatch is increased which is then compared with the number of passed rules, if they are equal the current evaluated item is saved.

At the end of the code and put encontrados2 and encontrados3 to reference that not only is it static for the school list, but you can pass other types.

I hope you will be a guide for what you need.

    
answered by 20.11.2018 / 21:21
source
1

To solve specifically the problem shown, this is the solution I found:

const escuelas = [
    {id_escolares_pk: 1,escuela: "Gregorio",tipo: "Pública",id_nivel_fk: 1},
    {id_escolares_pk: 2,escuela: "Ignacio",tipo: "Privada",id_nivel_fk: 1},
    {id_escolares_pk: 3,escuela: "UTZ",tipo: "Pública",id_nivel_fk: 1}
];

// Arreglo con las condiciones a ejecutar
const listaCondiciones = [
    { columna: "id_nivel_fk", valor: 1, operador: "===" },
    { columna: "tipo", valor: "Pública", operador: "!==" }
];

// Ejecución de filter 
const encontrados = escuelas.filter(elemento => cumpleLasCondiciones(elemento, listaCondiciones));

// Verifica todas las condiciones para el elemento dado
function cumpleLasCondiciones(elemento, condiciones) {
    return !condiciones
        .map(condicion => evaluarCondicion(elemento, condicion))
        .includes(false);
}

function evaluarCondicion(elemento, condicion) {
  if(condicion.operador === "===") 
      return elemento[condicion.columna] === condicion.valor;
  if(condicion.operador === "!==") 
      return elemento[condicion.columna] !== condicion.valor;
  if(condicion.operador === "==") 
      return elemento[condicion.columna] == condicion.valor;
  if(condicion.operador === "!=") 
      return elemento[condicion.columna] != condicion.valor;
  if(condicion.operador === "<")
      return elemento[condicion.columna] < condicion.valor;
  if(condicion.operador === "<=") 
      return elemento[condicion.columna] <= condicion.valor;
  if(condicion.operador === ">") 
      return elemento[condicion.columna] > condicion.valor;
  if(condicion.operador === ">=")
      return elemento[condicion.columna] >= condicion.valor;
} 

console.log(encontrados);

In cumpleLasCondiciones is where the magic happens.

map(condicion => elemento[condicion.columna] === condicion.valor) executes each check and returns true or false depending on whether it complies or not.

The resulting arrangement consists of the results of these evaluations, so we look for if some were not met with includes(false) .

Finally, if one was found that was not fulfilled ( includes returns true ), we deny the value with !condiciones , which in the end is used by the escuelas.filter to know if the element passes or not .

To add more operators, you can use the Orlando method, adding one more property to the comparisons object and creating a function to apply in map .

    
answered by 20.11.2018 в 21:52
-1

And I tried to do it with a join, adding an element within the array of comparisons, it does not give me an error but it does not respect the condition% var escuelas = [ {id_escolares_pk: 1,escuela: "Gregorio",tipo: "Pública",id_nivel_fk: 1}, {id_escolares_pk: 2,escuela: "Ignacio",tipo: "Privada",id_nivel_fk: 1}, {id_escolares_pk: 3,escuela: "UTZ",tipo: "Pública",id_nivel_fk: 1} ]; var comparaciones = ["elemento.id_nivel_fk == 1", "elemento.tipo == 'Privada' "]; /*◄ Aqui es donde agregué "elemento." seguido de la clave*/ var encontrados = escuelas.filter(function(elemento) { return comparaciones.join(' && '); /* ◄ Aplico un join agregando && para simulara esto ► elemento.id_nivel_fk == 1 && elemento.tipo == "Privada" */ }); console.log(encontrados); // Retorna el Objeto escuelas sin respetar la condición

I know it's not the way, but I thought maybe it would work

    
answered by 20.11.2018 в 19:43