具有多个参数的JavaScript过滤

时间:2020-08-07 19:04:08

标签: javascript filtering

我需要使用从字段中获取的多个参数来过滤内容。字段也可以为空,因此我需要获取所有不为空的值。然后按那些过滤。

实现这种目标的最佳方法是什么,而又不会产生很多if和else if情况:

if (a !== '' && b !== '' && c !== '' && d !== '' && e !== ''){
    // none is empty, filter by a & b & c & d & e
}

else if ( b !== '' && c !== '' && d !== '' && e !== ''){ 
    // a is empty, filter by b & c & d & e
}

else if ( a !== '' && c !== '' && d !== '' && e !== ''){ 
    // b is empty, filter by a & c & d & e
}

else if ( b !== '' && a !== '' && d !== '' && e !== ''){ 
}

else if ( b !== '' && c !== '' && a !== '' && e !== ''){ 
}

else if ( b !== '' && c !== '' && d !== '' && a !== ''){ 
}

else if ( c !== '' && d !== '' && e !== ''){
}

else if ( b !== '' && d !== '' && e !== ''){
}

else if ( b !== '' && c !== '' && e !== ''){ 
}

else if ( b !== '' && c !== '' && d !== ''){ 
}

else if ( a !== '' && d !== '' && e !== ''){ 
}

and so on...

或者,如何获得这5个字母的所有唯一可能组合?

编辑::

实际代码看起来像这样

  //a/b/c take value of dropdown items, that match with data on an object

    if (a != '' && b != '' && c != '') {

            for (const i in ParticipationList.TaskMetadata) {
                if (ParticipationList.TaskMetadata[i].attendance == a && ParticipationList.TaskMetadata[i].monitoring_status == b  && ParticipationList.TaskMetadata[i].monitoring_status == c) {
                            filteredaudience[i] = { ['id']: i }
                        }
            console.log(filteredaudience)
            // get all the items that match with the object properties
        }
    }

因此,如果abc为空,我仍然无法进行相同的调用,因为它与对象上的任何内容都不匹配。

4 个答案:

答案 0 :(得分:2)

逻辑:

由于javascript具有short-circuit evaluation,我们将只使用以下格式的条件:

field === "" || (condition to filter using field)

由于所说的“短路”,只有在该字段不为空时(即,如果左侧为false因为field !== ""才可以到达右侧部分)。但是,如果该字段为空,则field === ""将为true并且将不会到达右侧部分,整个条件将产生true,从而导致对该字段的过滤为跳过了。

多个条件应该由逻辑&&运算符连接在一起,并且这些条件中的每一个都应该用括号()括起来,因为运算符&&的优先级高于{{ 1}}运算符。

如果要过滤的数据是数组:

对于数组,只需使用条件作为从||的回调返回的值,就像这样:

filter

如果要过滤的数据是对象:

如果数据是对象,并且您不能像上面那样使用let filteredData = data.filter(item => (a === "" || (condition for field 'a' against 'item')) && (b === "" || (condition for field 'b' against 'item')) && (c === "" || (condition for field 'c' against 'item')) && (d === "" || (condition for field 'd' against 'item')) && (e === "" || (condition for field 'e' against 'item')) ); ,则仍然可以使用相同的逻辑,只需要像这样使用filter内的条件:

if

答案 1 :(得分:0)

根据实际过滤过程的工作方式,有可能逐步过滤结果而不是同时进行过滤。

例如,如果您的数据是数组,则可以编写:

let data = ...;
if (a != '') {
    data = data.filter(elem => checkForA(a, elem));
}
if (b != '') {
    data = data.filter(elem => checkForB(b, elem));
}
...

也许您还可以增量地增加过滤器对象本身,然后应用构建的过滤器。

答案 2 :(得分:0)

请输入更多详细信息... 目前,我了解到您想获得所有 不为空的值。

为此:

let allElements = [a, b, c, d, e]
let notEmpty = []

allElements.forEach(element => {
    if (element !== '')
        notEmpty.push(element)
});
console.log(notEmpty)

答案 3 :(得分:0)

对于新开发人员来说,一个常见的错误是创建带有大量&&和||的长,复杂和重复的if语句。符号或if / else if的长字符串

写一个简单的搜索谓词代替它。该函数需要一些参数,并将其减少为true或false。

在上述功能中,一次运行每个过滤器。一旦失败,则返回false。

var data = [
    { colour : "red", weight : 2, name : "Example 1"},
    { colour : "orange", weight : 15, name : "Example 2"},
    { colour : "yellow", weight : 10, name : "Test 1"},
    { colour : "green", weight : 24, name : "Test 2"}
];

console.log(search(data, "red", [], ""));

console.log(search(data, "", [5,20], ""));

console.log(search(data, "", [], "Test"));


function search(data, colour, weights, name) {
    return data.filter(row=>testRow(colour, weights, name, row));
}


// much easier to read.
function testRow(colourFilter, weightFilter, nameSearchFilter, row) {

    // run each filter one at a time. If any fail, "short circuit" out.
    if (colourFilter != "" && row.colour == colourFilter) {
        return false;
    }

    // sometimes, a double if statemnt is easier to read.
    if (weightFilter.length > 0) {
        if (row.weight < weightFilter[0] || row.weight > weightFilter[1]) {
            return false;
        }
    }

    // sometimes, the actual rule is a bit complex.
    if (nameSearchFilter != "") {
        if (row.name.indexOf(nameSearchFilter) < 0) {
            return false;
        }
    }

    // we survived all filters.
    return true;
}