首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Javascript多条件数组过滤器

Javascript多条件数组过滤器
EN

Stack Overflow用户
提问于 2017-01-13 10:05:40
回答 5查看 54K关注 0票数 6

我需要帮助来组织一个基于多个条件的数组搜索。此外,所有条件都是有条件的,这意味着我可能需要也可能不需要过滤这些条件。我所拥有的:

要筛选的对象数组:

代码语言:javascript
复制
var data = [{
    "_id" : ObjectId("583f6e6d14c8042dd7c979e6"),
    "transid" : 1,
    "acct" : "acct1",
    "transdate" : ISODate("2012-01-31T05:00:00.000Z"),
    "category" : "category1",
    "amount" : 103
},
{
    "_id" : ObjectId("583f6e6d14c8042dd7c2132t6"),
    "transid" : 2,
    "acct" : "acct2",
    "transdate" : ISODate("2012-01-31T05:00:00.000Z"),
    "category" : "category2",
    "amount" : 103
},
{
    "_id" : ObjectId("583f6e6d14c8042dd7c2132t6"),
    "transid" : 3,
    "acct" : "acct2",
    "transdate" : ISODate("2016-07-31T05:00:00.000Z"),
    "category" : "category1",
    "amount" : 103
},
{
    "_id" : ObjectId("583f6e6d14c8042dd7c2132t6"),
    "transid" : 4,
    "acct" : "acct2",
    "transdate" : ISODate("2012-01-31T05:00:00.000Z"),
    "category" : "category2",
    "amount" : 103
},
{
    "_id" : ObjectId("583f6e6d14c8042dd7c2132t6"),
    "transid" : 5,
    "acct" : "acct2",
    "transdate" : ISODate("2012-01-31T05:00:00.000Z"),
    "category" : "category3",
    "amount" : 103
},
{
    "_id" : ObjectId("583f6e6d14c8042dd7c152g2"),
    "transid" : 6,
    "acct" : "acct3",
    "transdate" : ISODate("2016-10-31T05:00:00.000Z"),
    "category" : "category3",
    "amount" : 103
}]

我根据另一个混合元素数组过滤上面的对象数组。这些元素表示以下搜索字段:

  • "searchstring":在数据数组中的所有字段中搜索任何匹配的文本序列
  • 对象,其键值表示帐户类型,值为true或false指示是否应将其用于筛选
  • startdate筛选
  • enddate上的交易记录筛选

name以筛选上的类别

具有搜索条件的数组如下所示(但如果某些字段不是必需的,它们将被设置为未定义或仅为空字符串或数组):

代码语言:javascript
复制
var filtercondition = {
    "p",
    {acct1:true,acct2:false,acct3:true...}
    "2016-06-01",
    "2016-11-30",
    "category3"
}

实现这一目标的最佳方法是什么?我设计的是对过滤器数组中的每个元素进行单独搜索,但这似乎不是最优的,而且非常繁琐。我愿意重新设计我的设置...

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2017-01-13 10:25:45

代码语言:javascript
复制
// You wrote that it's an array, so changed the braces 
var filtercondition = ["p",
{acct1:true,acct2:false,acct3:true...}
"2016-06-01",
"2016-11-30",
"category3"
];

var filtered = data.filter(o => {
    if(filtercondition[0] && !o.category.includes(filtercondition[o])) { // checking just the category, but you can check if any of more fields contains the conditions 
        return false;
    }
    if(filtercondition[1]) {
        for(var key in filtercondition[1]) {
        if(filtercondition[1][key] === true && o.acct != key) {
            return false;
        }
        }
    }
    if(filtercondition[2] && o.transdate < filtercondition[2]) {
        return false;
    }
    if(filtercondition[3] && o.transdate > filtercondition[3]) {
        return false;
    }
    if(filtercondition[4] && o.category !== filtercondition[4]) {
        return false;
    }

    return true;
});

注意两点:-更改了filtercondition的大括号,使其成为一个数组,但我建议使用对象。+这个{acct1:true,acct2:false,acct3:true...}示例对我来说没有意义,因为它建议acct字段应该同时为acct1acct3

票数 6
EN

Stack Overflow用户

发布于 2017-01-13 10:20:24

创建一个函数数组,每个函数代表一个条件。

下面是一些示例代码,演示了这种方法。

代码语言:javascript
复制
 var conditions = [];

 // Dynamically build the list of conditions
 if(startDateFilter) {
    conditions.push(function(item) { 
       return item.transdate >= startDateFilter.startDate;
    });
 };

 if(categoryFilter) {
     conditions.push(function(item) {
         return item.cateogry === categoryFilter.category;
     });
 };
 // etc etc

一旦有了条件数组,就可以使用Array.prototype.every对项目运行每个条件。

代码语言:javascript
复制
 var itemsMatchingCondition = data.filter(function(d) {
     return conditions.every(function(c) {
         return c(d);
     });
 });

或者,使用更紧凑的箭头函数:

代码语言:javascript
复制
const itemsMatchingCondition = data.filter(d => conditions.every(c => c(d));
票数 5
EN

Stack Overflow用户

发布于 2017-01-13 10:18:25

首先,您需要对数组使用括号,而不是大括号:

代码语言:javascript
复制
var filtercondition = [
    "p",
    {acct1:true,acct2:false,acct3:true...},
    "2016-06-01",
    "2016-11-30",
    "category3"
];

再说一次,我不认为数组是最好的数据类型。尝试像这样的对象:

代码语言:javascript
复制
var filtercondition = {
    query: "p",
    accounts: {acct1:true,acct2:false,acct3:true...},
    date1: "2016-06-01",
    date2: "2016-11-30",
    category: "category3"
};

然后,尝试使用Array.prototype.filter:

代码语言:javascript
复制
var filtered = data.filter(function(obj) {
    for (var key in filtercondition) {
        // if condition not met return false
    }
    return true;
});
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41626302

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档