Reputation:
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]]))
Upvotes: 4
Views: 4190
Reputation: 16908
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));
Upvotes: 0
Reputation: 386868
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);
Upvotes: 6
Reputation: 50346
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
Upvotes: 0