How to write multiple sentences AND for an unknown number of conditions

I wonder if this can be done in Javascript?

I have a set of conditions, which is a set of filtering criteria for a report

Just say that these are possible filter criteria: (a few pseudo-code, don't worry about the actual JSON structure)

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

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

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

Now I want to allow the user to filter data, for example Employee which job is either developer or tester who work hourly

In this case I will have javascript like

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

but then, if the user wants to add additional parameters to the filter, for example, on top of this, a filter for employees who work remotely, for example office = 'remote'

I would need to write something like

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

, , , , , , , , ?

.

+4
3

jsFiddle Demo

, , :

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'});

json-. , :

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

json. , . . . . , , .

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

, :

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

Try it out and see if it fits your needs.
0

Based on Salman's code, but simpler:

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

Used data:

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

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

var jane = {
    job: 'developer',
    salary: 'monthly',
    office: 'remote'
};
0
source

All Articles