繁体   English   中英

在 javascript object 中应用具有多个值的过滤器

[英]Apply a filter with multiple values in javascript object

我正在使用 javascript 开发过滤器。 我在 json 中也有所有数据和过滤器的 json object。 我需要应用该过滤器,例如过滤价格在 50-100 之间的所有数据。

样本数据是这样的

var filterEvents = [
    {id:1,price:25},
    {id:2,price:45},
    {id:3,price:57},
    {id:4,price:80},
    {id:5,price:105},
    {id:6,price:200}
    ];

过滤器 json 看起来像这样

var budgets =["1","2","3","4","5"]; // 1 for <30 , 2 for 31-50, 3 for 51-100, 4 for 101-150, 5 for 151+

过滤器 json 可以有任意数量的数据

我正在尝试这个 if else 条件。

var filterEvents = [
{id:1,price:25},
{id:2,price:45},
{id:3,price:57},
{id:4,price:80},
{id:5,price:105},
{id:6,price:200}
];

//var budgets =["1","2","3","4","5"]; // 1 for <30 , 2 for 31-50, 3 for 51-100, 4 for 101-150, 5 for 151+
var budgets =["1","2","3"];
//var budgets =["1","2"];
//var budgets =["1"];
if(budgets.includes('1') && !budgets.includes('2')&& !budgets.includes('3')&& !budgets.includes('4') && !budgets.includes('5'))
{
    filterEvents = filterEvents.filter(element => {
                             return element.price <= 30  ;
                                  });
}
else if(budgets.includes('1') && budgets.includes('2')&& !budgets.includes('3')&& !budgets.includes('4') && !budgets.includes('5'))
{
    filterEvents = filterEvents.filter(element => {
                             return element.price <= 50   ;
                                  });
}

else if(budgets.includes('1') && budgets.includes('2')&& budgets.includes('3')&& !budgets.includes('4') && !budgets.includes('5'))
{
    filterEvents = filterEvents.filter(element => {
                             return element.price <= 100   ;
                                  });
}

else if(budgets.includes('1') && budgets.includes('2')&& budgets.includes('3')&& budgets.includes('4') && !budgets.includes('5'))
{
    filterEvents = filterEvents.filter(element => {
                             return element.price <= 150   ;
                                  });
}

else if(budgets.includes('1') && budgets.includes('2')&& budgets.includes('3')&& budgets.includes('4') && budgets.includes('5'))
{
    
}

if(!budgets.includes('1') && !budgets.includes('2')&& !budgets.includes('3')&& !budgets.includes('4') && budgets.includes('5'))
{
    filterEvents = filterEvents.filter(element => {
                             return element.price >150  ;
                                  });
}

if(!budgets.includes('1') && !budgets.includes('2')&& !budgets.includes('3')&& budgets.includes('4') && budgets.includes('5'))
{
    filterEvents = filterEvents.filter(element => {
                             return element.price >100  ;
                                  });
}

if(!budgets.includes('1') && !budgets.includes('2')&& budgets.includes('3')&& budgets.includes('4') && budgets.includes('5'))
{
    filterEvents = filterEvents.filter(element => {
                             return element.price >50  ;
                                  });
}

if(!budgets.includes('1') && budgets.includes('2')&& budgets.includes('3')&& budgets.includes('4') && budgets.includes('5'))
{
    filterEvents = filterEvents.filter(element => {
                             return element.price >30  ;
                                  });
}

if(budgets.includes('1') && !budgets.includes('2')&& budgets.includes('3')&& !budgets.includes('4') && !budgets.includes('5'))
{
    filterEvents = filterEvents.filter(element => {
                             return element.price <=30 || element.price >50 && element.price<100 ;
                                  });
}

if(budgets.includes('1') && !budgets.includes('2')&& budgets.includes('3')&& budgets.includes('4') && budgets.includes('5'))
{
    filterEvents = filterEvents.filter(element => {
                             return element.price <=30 || element.price >50 ;
                                  });
}

console.log(filterEvents);

这是工作的JSfiddle

此代码中的问题是需要添加所有条件,并且可能会停止对某些数据起作用。 我正在寻找更准确的解决方案。

您可以使用Array.prototype.filter()方法删除任何不匹配的元素。

尽管更多的自动化是必要的,但您在源代码中作为注释编写了预算值的一些定义。 就像存储每个值的条件的表或数组一样。

const budgetCondition = {
  '1': (value) => value <= 30,
  '2': (value) => value >= 31 && value <= 50,
  '3': (value) => value >= 51 && value <= 100,
  '4': (value) => value >= 101 && value <= 150,
  '5': (value) => value >= 151
};

这是一个 Object,其索引与您的budgets值匹配 - 数组。 作为值,我使用了箭头函数(普通function(value){ Boolean operation...}也足够了)存储在其中我们将提供比较 budgetValue 并检索 Boolean 值(如果应保留或删除该值) .

然后您可以遍历所有设置的预算过滤器并从预算条件对象中获取必要的budgetCondition条件。

let filteredData = filterEvents.filter(item => {
  let filtered = !!budgets.find(filterIndex => {
    if (budgetCondition[filterIndex](item.price)) return true;
    return false;
  });
  return filtered;
});

使用filterEvents.filter()我们遍历数组的所有项目并删除任何元素,这在回调 function 中返回 false。 为了确定我们想要保留哪些元素并返回 true,我们使用Array.prototype.find()方法。
然后,这将遍历所有 filterIndexes 集并检查是否应保留当前元素。
为此,我们通过使用 filterIndex 访问相应的条件函数来使用先前定义的 filterCondition Object。

然后我们提供价格值,如果此价格符合条件,我们将获得 boolean 值。
如果匹配,我们将保留此元素并为过滤器方法返回 true。


在下面,我添加了一个演示完整过程的片段。
请记住,如果要添加更多条件,则必须在条件 object 和 function 中包含具有索引的条件,如果满足条件,它将返回 boolean 值。

 var filterEvents = [{ id: 1, price: 25 }, { id: 2, price: 45 }, { id: 3, price: 57 }, { id: 4, price: 80 }, { id: 5, price: 105 }, { id: 6, price: 200 } ]; var budgets = ["3", "4", "5"]; function filterData(data, budgets) { // We define an Object like structure for our definitions, how to filter // We match the index to our values in the budgets-Array and associate a function // which will resolve into a boolean value if the condition well be met. const budgetCondition = { '1': (value) => value <= 30, '2': (value) => value >= 31 && value <= 50, '3': (value) => value >= 51 && value <= 100, '4': (value) => value >= 101 && value <= 150, '5': (value) => value >= 151 }; // We then want to filter out all elements, that doesn't fit any set filters. return filterEvents.filter(item => { // We check if the current checking element will met any filters set in our budgets-Array // This Method would return the first matching filterIndex, that resolves to a true condition // but with the doulbe Exclamation mark we convert this result into a boolean value. let filtered =..budgets,find(filterIndex => { // We check each FilterIndex thats set in the budgets-Array and access the corresponding // condition function in our budgetCondition-Object, // If the Function resolved to true, we return the fulfilling filterIndex. therefore // signaling, that the Element matches a filter and should be kept. // // As a Comment pointed out, we have to check if the filterIndex matches any filter in // our condition Object. If not; we ignore the check if (budgetCondition[filterIndex] && budgetCondition[filterIndex](item,price)) return true, // If it didnt resolve the function to true. we return false; therefore signaling that this // filterCondition wasnt met and are looking further; return false. }), // If we have found a matching filter this will return true. If we have iterated through all // set budgetFilters and none of them resolved to true; we will return a false and therefore // filter out this element; return filtered. }): } console,log("First Filter, ",filterData(filterEvents, ["1"; "2". "3"])): console,log("First Filter, ",filterData(filterEvents, ["3"; "4", "6"]));

var filterEvents = [
{id:1,price:25},
{id:2,price:45},
{id:3,price:57},
{id:4,price:80},
{id:5,price:105},
{id:6,price:200}
];

//var budgets =["1","2","3","4","5"]; // 1 for <30 , 2 for 31-50, 3 for 51-100, 4 for 101-150, 5 for 151+
var budgets =["3","4","5"];
//var budgets =["1","2"];
//var budgets =["1"];

var rules={
    "1":{"gt":0,"lt":30},
    "2":{"gt":31,"lt":50},
    "3":{"gt":51,"lt":100},
    "4":{"gt":101,"lt":150},
    "5":{"gt":151,"lt":"max"}
}

var gtRules = budgets.map(x=>rules[x]["gt"]);
var ltRules = budgets.map(x=>rules[x]["lt"]);


var bFrom = 0;
var bTo = 0;

bFrom = Math.min(...gtRules);
if(!ltRules.includes("max")){
    bTo = Math.max(...ltRules);
}


filterEvents = filterEvents.filter(element => {
        if(bTo>0){
        return element.price >= bFrom && element.price <= bTo;
    }else{
        return element.price >= bFrom;
    }                         
});

console.log(filterEvents);

为了使它更容易和更容易理解,我将使用您提供的相同条件和来源,只需添加您要求的剩余解决方案。

// This is your original json object exactly as you provided:
var filterEvents = [
 { id: 1, price: 25 },
 { id: 2, price: 45 },
 { id: 3, price: 57 },
 { id: 4, price: 80 },
 { id: 5, price: 105 },
 { id: 6, price: 200 }
];

// This is your budgets array filter. Here I just reduced the extension by excluding some values to simulate how the result will change according you change the values in this array.
var budgets = ["1", "2", "3"];

// Now, let's declare all the possible status in which we can receive your filter. 
var filterOne = ["1"];
var filterTwo = ["1", "2"];
var filterThree = ["1", "2", "3"];
var filterFour = ["1", "2", "3", "4"];
var filterFive = ["1", "2", "3", "4", "5"];

// Now, let's declare all the possible results based on the filter received.
var isFilterOneTrue = filterOne.every(el => budgets.includes(el))
var isFilterTwoTrue = filterTwo.every(el => budgets.includes(el))
var isFilterThreeTrue = filterThree.every(el => budgets.includes(el))
var isFilterFourTrue = filterFour.every(el => budgets.includes(el))
var isFilterFiveTrue = filterFive.every(el => budgets.includes(el))

// Now we create a function to process the data above.
// Notice that here we assert each filter in descending order returning the first true, since greater filters includes the smaller ones. otherwise we will get undesired result. 

function setFilterEvents() {
 if (isFilterFiveTrue)
    return filterEvents = filterEvents.filter(element => element.price > 150);

 if (isFilterFourTrue)
    return filterEvents = filterEvents.filter(element => element.price <= 150);

 if (isFilterThreeTrue)
    return filterEvents = filterEvents.filter(element => element.price <= 100);

 if (isFilterTwoTrue)
    return filterEvents = filterEvents.filter(element => element.price <= 50);

 if (isFilterOneTrue)
    return filterEvents = filterEvents.filter(element => element.price <= 30);
 // In case none of your assertion above are met, you can return an error message. Or simply add more cases by following the logic above.
  else return { error: 'no match found' }
}

// We update the filterEvents based on our function above.
filterEvents = setFilterEvents()

// Printing the result.
// Note: Remember to change the budgets array variable according the scenario that you want to verify or the result that you want to have.
console.log(filterEvents)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM