简体   繁体   中英

Filter the JSON array of objects according to multiple conditions

I have a JSON array of object. I am creating a filter to filter this data.

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"
     }
]}

If Filter condition is: (Find items where orderNumbers contains 10)

Then Output:

{
  "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"
     }
]}

If Filter condition is: (Find items where orderNumbers contains 114)

Then Output:

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

If Filter condition is: (Find items where orderNumber contains 10 and area contains EM)

Then Output:

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

Is there a way to achieve concatenation of successive filters?

EDIT: I am trying to make it general.

I have stored the filter field values in state object.

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

Array selectedFilters stores the filters.

Like this:

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

How can i iterate now and achieve desired filter. I am trying to loop through selectedFilters array and check for each item that includes desired string. I don't know how to fill the blank with JSON object field based on selectedFilters array. Some sort of mapping between both is required. Let's say if selectedFilters[1] = orderNumberData, then orderNumber should go in that blank.

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

This works if i have hard coded the JSON fields.

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

You could move the constraints info a filter array and filter by checking all (AND condition) constraints with Array#every or if you want only some (OR condition), take 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); 

You can use filter,but since orderNumber is an integer use toString to convert it to string and then use includes to check if the values contains the desired number

 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) 

You can further fine tune the filter callback to integrate search for EM

We can get a dynamic filtering done by placing the filter criteria in an external array. In my example it is filterCond array.

Then iterate over the filter conditions array and check each value of the object property whether that is matching with the data in the filterCond array in the same index.

If the condition is false increment a counter, and return false if counter is greater than 0.

The criterias should be placed as per the index of the keys in the object.

 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)); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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