¿Te preguntas si esto es posible hacerlo en Javascript?

Tengo un conjunto de condiciones que es un conjunto de criterios de filtro para un informe

Simplemente diga que estos son los posibles criterios de filtro: (algo de pseudocódigo, no se preocupe por la estructura JSON real),

'job' = 'developer'
'job' = 'tester'
'job' = 'manager'

'salary' = 'hourly'
'salary' = 'weekly'
'salary' = 'monthly'

'office' = 'downstairs'
'office' = 'upstairs'
'office' = 'remote'

Ahora quiero permitir que el usuario filtre datos, por ejemplo Employee which job is either developer or tester who work hourly

En este caso tendría un javascript como

if ('salary' == 'hourly' && ('job' == 'tester' || 'job' == 'developer')){
  return true;
}

Pero luego, si el usuario desea agregar una dimensión adicional al filtro, por ejemplo, además de eso, filtre para los empleados que trabajan de forma remota, por ejemplo, office = 'remote'

Tendría que escribir algo como

if ('salary' == 'hourly' && ('job' == 'tester' || 'job' == 'developer') && ('office' == 'remote')){ return true; }

Mi pregunta es, ¿es posible construir estas condiciones AND mediante programación, tal vez iterando a través de una serie de criterios de filtro, en lugar de explicarlas manualmente como lo hice anteriormente?

Cualquier ayuda sería apreciada.

4
Mariatta 29 ago. 2014 a las 21:27

3 respuestas

La mejor respuesta

jsFiddle Demo

Estructuraría los argumentos enviados por clave y valor, como este:

var terms = [];
terms.push({'job':'developer'});
terms.push({'job':'tester'});
terms.push({'job':'manager'});

terms.push({'salary':'hourly'});
terms.push({'salary':'weekly'});
terms.push({'salary':'monthly'});

terms.push({'office':'downstairs'});
terms.push({'office':'upstairs'});
terms.push({'office':'remote'});

Debería ser muy fácil hacer esto con datos json. A continuación, prepararía un objeto de valores que contenía los datos de muestra como este:

var values = {
  job: 'tester',
  salary: 'monthly',
  office: 'onsite'
};

Lo que también debería ser fácil de manipular desde el json. Tomando estos, los términos podrían iterarse y colocarse en cubos. Cada cubo será o tendrá consigo mismo. Cada resultado de ese cubo será y tendrá consigo mismo. Y el resultado final será la veracidad general. En la demostración, mire en la consola algunos de los registros de marca de verificación.

function test(terms,values){
 var sets = {};
 for(var i in terms)
 {
  for(var term in terms[i]){
   sets[term] = sets[term] || [];
   sets[term].push(terms[i][term]);
  }
 }
 var truthValues = [];
 for(var key in sets){
   var truth = false;
   for(var val in sets[key]){
    console.log(values[key] +" == "+sets[key][val]);
    truth |= values[key] == sets[key][val];      
   }
   truthValues.push(truth);
 }
 console.log(truthValues);
 var endTruth = true;
 for(var bool in truthValues){
  endTruth &= truthValues[bool];       
 }
 return endTruth;
}

console.log(test(terms,values));
1
Travis J 29 ago. 2014 a las 17:52

Basado en el código de Salman, pero más simple:

var matches = function (candidate, criteria) {
    return !Object.keys(criteria).some(function (k) {
        return criteria[k].indexOf(candidate[k]) < 0;
    });
};

Datos utilizados:

var criteria = {
    job: ['developer'],
    salary: ['weekly', 'monthly']
};

var john = {
    job: 'developer',
    salary: 'hourly',
    office: 'downstairs'
};

var jane = {
    job: 'developer',
    salary: 'monthly',
    office: 'remote'
};
0
kornieff 29 ago. 2014 a las 23:34

Llego un poco tarde a la fiesta, pero esto es lo que se me ocurrió:

var employees = [
    {name: 'Hannah', job: 'tester', salary: 'weekly', office: 'remote'},
    /* ... */
];

function getFilters(){
    document.getElementById("main").innerHTML = "";
    // reset the filters
    var filters = {job: [], salary: [], office: []};
    // populate them with checkboxes values
    for(prop in filters){
        var els = document.getElementsByName(prop);
        for(var i=0; i<els.length; i++){
            if(els[i].checked) filters[prop].push(els[i].id);
        }
    }
    // apply the filters
    applyFilters(filters);
}

function applyFilters(filters){
    var count = employees.length;
    // for each employee
    for(var i=0; i<count; i++){
        var e = employees[i];
        var meetsRequirements = true;
        // see if each property is in the filters
        for(prop in e){
            if(prop != "name" && filters[prop].indexOf(e[prop])==-1) meetsRequirements = false;
        }
        // if it is the case, display it
        if(meetsRequirements) displayEmployee(e);
    }
}

function displayEmployee(e){
    document.getElementById("main").insertAdjacentHTML( 'beforeend', "<div class='employee'><h4>" + e.name + "</h4><p>" + e.job + "</p><p>" + e.salary + "</p><p>" + e.office + "</p></div>" );
}

JS Fiddle Demo

Pruébelo y vea si se ajusta a sus necesidades

0
blex 29 ago. 2014 a las 18:58