如何为未知数量的条件编写多个AND子句

时间:2014-08-29 17:27:30

标签: javascript

想知道这是否可以在Javascript中进行?

我有一组条件,这是一组报告的过滤条件

只是说这些是可能的过滤条件:(有点伪代码,不要担心实际的JSON结构),

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

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

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

现在我想让用户过滤数据,例如Employee which job is either developer or tester who work hourly

在这种情况下,我会有一个javascript,如

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

但是如果用户想要为过滤器添加额外的维度,例如,最重要的是,过滤远程工作的员工,例如office = 'remote'

我必须写类似

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

我的问题是,是否有可能通过迭代一系列过滤条件来构建这些AND条件,而不是像我上面那样手动拼写它们?

任何帮助都将不胜感激。

3 个答案:

答案 0 :(得分:1)

<强> jsFiddle Demo

我将构造由key和value发送的参数,例如:

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 :(得分:0)

我参加聚会有点晚了,但这就是我想出的:

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.

答案 2 :(得分:0)

基于Salman的代码,但更简单:

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

使用的数据:

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

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

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