根据多种条件过滤对象的JSON数组

时间:2019-04-18 17:42:35

标签: javascript json

我有一个JSON对象数组。我正在创建一个过滤器来过滤这些数据。

var allData = {
  "items":[
     {
       "orderNumber": 1010,
       "area": "JAPAN",
       "category": "orange",
       "orderApprover": "John Smith"
     },
     {
       "orderNumber": 1020,
       "area": "EM-JAPAN",
       "category": "red",
       "orderApprover": "Paul Smith"
     },
     {
       "orderNumber": 1013,
       "area": "EMEA",
       "category": "orange",
       "orderApprover": "Mike Smith"
     },
     {
       "orderNumber": 1140,
       "area": "APAC",
       "category": "yellow",
       "orderApprover": "Jake Smith"
     }
]}

如果过滤条件为:(查找orderNumber包含10的项目)

然后输出:

{
  "items":[
     {
       "orderNumber": 1010,
       "area": "JAPAN",
       "category": "orange",
       "orderApprover": "John Smith"
     },
     {
       "orderNumber": 1020,
       "area": "EM-JAPAN",
       "category": "red",
       "orderApprover": "Paul Smith"
     },
     {
       "orderNumber": 1013,
       "area": "EMEA",
       "category": "orange",
       "orderApprover": "Mike Smith"
     }
]}

如果过滤条件为:(查找orderNumber包含114的项目)

然后输出:

{
  "items":[
    {
      "orderNumber": 1140,
      "area": "APAC",
      "category": "yellow",
      "orderApprover": "Jake Smith"
    }
]
}

如果过滤条件为:(查找orderNumber包含10且区域包含EM的项目)

然后输出:

{
  "items":[
     {
       "orderNumber": 1020,
       "area": "EM-JAPAN",
       "category": "red",
       "orderApprover": "Paul Smith"
     },
     {
       "orderNumber": 1013,
       "area": "EMEA",
       "category": "orange",
       "orderApprover": "Mike Smith"
     }
]}

有没有办法实现连续过滤器的串联?

编辑:我正在尝试使其更笼统。

我已将过滤器字段值存储在状态对象中。

this.state = {
  orderNumberData: '',
  areaData: '',
  .
  .
  .
  .
}

selectedFilters数组存储过滤器。

赞:

selectedFilters = [orderNumberData, areaData,........]

我现在如何迭代并获得所需的过滤器。我试图遍历selectedFilters数组,并检查包含所需字符串的每个项目。我不知道如何使用基于selectedFilters数组的JSON对象字段填充空白。两者之间需要某种映射。假设如果selectedFilters [1] = orderNumberData,那么orderNumber应该在该空白处。

for(var i=0; i<selectedFilters.length; i++) {
   allData.items.filter(item => item.________.toString().includes(this.state[this.state.selectedFilters[i]]))
}

如果我对JSON字段进行了硬编码,则此方法有效。

allData.items.filter(item => item.orderNumber.toString().includes(this.state[this.state.selectedFilters[i]]))

3 个答案:

答案 0 :(得分:6)

您可以将约束信息移动到一个过滤器数组中,并通过使用Array#every检查所有(与条件)约束来进行过滤,或者如果您只想要一些(或条件),则采用Array#some

var data = [{ orderNumber: 1010, area: "JAPAN", category: "orange", orderApprover: "John Smith" }, { orderNumber: 1020, area: "EM-JAPAN", category: "red", orderApprover: "Paul Smith" }, { orderNumber: 1013, area: "EMEA", category: "orange", orderApprover: "Mike Smith" }, { orderNumber: 1140, area: "APAC", category: "yellow", orderApprover: "Jake Smith" }],
    filters = [
        o => o.orderNumber.toString().includes('10'),
        o => o.area.includes('EM')
    ],
    result = data.filter(o => filters.every(fn => fn(o)));

console.log(result);

答案 1 :(得分:1)

您可以使用过滤器,但是由于orderNumber是整数,请使用toString将其转换为字符串,然后使用includes检查值是否包含所需的数字

var allData = {
  "items": [{
      "orderNumber": 1010,
      "area": "JAPAN",
      "category": "orange",
      "orderApprover": "John Smith"
    },
    {
      "orderNumber": 1020,
      "area": "EM-JAPAN",
      "category": "red",
      "orderApprover": "Paul Smith"
    },
    {
      "orderNumber": 1013,
      "area": "EMEA",
      "category": "orange",
      "orderApprover": "Mike Smith"
    },
    {
      "orderNumber": 1140,
      "area": "APAC",
      "category": "yellow",
      "orderApprover": "Jake Smith"
    }
  ]
}



let data = allData.items.filter(item => item.orderNumber.toString().includes('10'));

console.log(data)

您可以进一步微调过滤器回调以集成对EM的搜索

答案 2 :(得分:1)

我们可以通过将过滤条件放置在外部阵列中来进行动态过滤。在我的示例中,它是filterCond数组。

然后遍历过滤条件数组,并检查对象属性的每个值是否与 same 索引中的filterCond数组中的数据匹配。

如果条件为false,则增加一个计数器,如果计数器大于0,则返回false。

应该根据对象中键的索引放置条件。

var allData = {"items":[{ orderNumber: 1010, area: "JAPAN", category: "orange", orderApprover: "John Smith" }, { orderNumber: 1020, area: "EM-JAPAN", category: "red", orderApprover: "Paul Smith" }, { orderNumber: 1013, area: "EMEA", category: "orange", orderApprover: "Mike Smith" }, { orderNumber: 1140, area: "APAC", category: "yellow", orderApprover: "Jake Smith" }]};

function getFilteredData(allData, filterCond){
 return allData.items.filter((itm) =>{
  count = 0;
  filterCond.forEach((cond, idx) => {
     count = Object.values(itm)[idx].toString().includes(cond) === false ? count + 1: count;
  })
  return count === 0;
});
}
console.log("Filtering by orderNumber 10 and area EM");
let filterCond = ["10", "EM"];
console.log(getFilteredData(allData, filterCond));

console.log("Filtering by orderNumber 114");
filterCond = [114];
console.log(getFilteredData(allData, filterCond));

console.log("Filtering by only orderNumber 10");
filterCond = [10];
console.log(getFilteredData(allData, filterCond));

console.log("Filtering by only area APAC");
filterCond = [, "APAC"]; //leaving first criteria blank
console.log(getFilteredData(allData, filterCond));