javascript filter array multiple conditions
You can do like this
var filter = {
address: 'England',
name: 'Mark'
};
var users = [{
name: 'John',
email: 'johnson@mail.com',
age: 25,
address: 'USA'
},
{
name: 'Tom',
email: 'tom@mail.com',
age: 35,
address: 'England'
},
{
name: 'Mark',
email: 'mark@mail.com',
age: 28,
address: 'England'
}
];
users= users.filter(function(item) {
for (var key in filter) {
if (item[key] === undefined || item[key] != filter[key])
return false;
}
return true;
});
console.log(users)
Filter Array with multiple conditions in other array of options
I don't think flattening the filters is the right idea, because then you'll be mixing the different properties. Iterate over the filters object instead, and have the item pass the test if, for every filter property:
- the filter is empty, or
- the same property on the object being iterated over exists in the filter array
const data = [
{id: 1, name: 'john', location: 'NY', age: '50'},
{id: 2, name: 'mj', location: 'LA', age: '41'},
{id: 3, name: 'mike', location: 'LA', age: '50'},
{id: 4, name: 'lebron', location: 'SF', age: '20'},
{id: 5, name: 'mike', location: 'NY', age: '60'},
{id: 6, name: 'john', location: 'MI', age: '30'},
{id: 7, name: 'mj', location: 'NY', age: '53'}
];
const filters = {
name: ['mike', 'mj'],
location: ['NY'],
age: []
};
const filtered = data.filter(obj =>
Object.entries(filters).every(([key, filterArr]) => (
filterArr.length === 0 || filterArr.includes(obj[key])
))
);
console.log(filtered);
How to filter array of objects on multiple conditions and add exception?
I kept the filtering part you implemented as an intermediate output. using that i got a count for each id. then using that i filtered out from the intermediate array where if the has count > 1 and has a null name i remove it.
const data = [{id: 1234,name: "Name1"},{id: 1234,name: "Name1"},{id: 1234,name: "Name2"},{id: 1234,name: null},{id: 5678,name: "Name3"},{
id: 5678,name: "Name3"},{id: 5678,name: null},{id: 9999,name: null},{id: 9999,name: null},];
//filtering out duplicates
let a = data.filter((value, index, self) => {
return (
self.findIndex(
(v) =>
v.id === value.id &&
v.name=== value.name
) === index
);
});
//get count for ids in partially filtered
let idcount = a.reduce((acc,curr) => {
if(!acc[curr.id])acc[curr.id] = 0
acc[curr.id] += 1
return acc;
},{})
//remove the duplicate nulls
let final = a.filter((el) => {
return !(idcount[el.id]>1 && el.name===null)
})
console.log(final)
Filtering an array of objects with multiple filter conditions
Use Object.entries()
on filters
to get an array of [key, values]
pairs. Iterate the pairs with Array.every()
, and check that each pair includes the value of the current object.
const fn = (arr, filters) => {
const filtersArr = Object.entries(filters)
return arr.filter(o =>
filtersArr.every(([key, values]) =>
values.includes(o[key])
)
)
}
const users = [{"name":"Mark","location":"US","job":"engineer"},{"name":"Mark","location":"US","job":"clerk"},{"name":"Angela","location":"Europe","job":"pilot"},{"name":"Matthew","location":"US","job":"engineer"}]
const filters = {
name: ["Mark", "Matthew"],
location: ["US"],
job: ["engineer"]
}
const result = fn(users, filters)
console.log(result)
Filter array of object based on multiple conditions in React
The issue is that you are applying all of your filters instead of just ones that are defined. And also you also should just return false from your filters if they are defined, that is the only way to run through all of them. So your code should look something like this
const filteredAllPersons = oldPersons.filter(person => {
if (genderFilter && person.gender !== genderFilter) {
return false
}
// apply all other filters the same as above
// Finally return true because record has satisfied all conditions
return true
})
Javascript multiple condition array filter
// 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;
});
Two notes:
- changed the braces of filtercondition
so that it is an array, however I would suggest to use an object instead.
- this {acct1:true,acct2:false,acct3:true...}
sample doesn't make sense for me, since it suggests that the acct
field should be acct1
and acct3
at the same time.
JavaScript multiple condition filtering with array of conditions?
You can use a higher order filter function to handle applying filter conditions and is passed to your array.prototype.filter function.
const filterData = ({ filters = [], every = false }) => (el) =>
filters[every ? "every" : "some"]((filterFn) => filterFn(el));
This consumes an options object that defines an array of filter condition functions that accept a single element value/object from your data array and returns the function used for the array filtering.
Example:
// AC AND nonAC
data.filter(filterData({
filters: [
({ AC, nonAC }) => AC && nonAC,
],
}))
Note
If your data is in the form
"AC": "false"
Where the booleans are stringified then make the following adjustment to your condition checkers, compare to === 'true'
:
({ AC, nonAC }) => AC === "true" || nonAC === "true"
Edit
After discussion it seems some of these conditions are not mutually inclusive, or rather, they are only mutually inclusive in specific groups.
Still using a Higher Order Function, the logic is tweaked a bit to consume the array of key-value conditions.
Create a mapping function to map your user selected filters ([{ AC: "true" }, ...]
) to a groups of "filterBy" values that are mutually inclusive. These will be logical OR'd (||
) together while the sets will be exclusive by using logical AND'd (&&
) together.
const mapfiltersToSets = (filters) => {
const filtersObject = filters.reduce((conditions, condition) => {
const [key, value] = Object.entries(condition).pop();
switch (key) {
case "AC":
case "nonAC":
return {
...conditions,
acConditions: [...(conditions.acConditions || []), { key, value }]
};
case "seater":
case "sleeper":
return {
...conditions,
seatSleeper: [...(conditions.seatSleeper || []), { key, value }]
};
// add new AND groups here
default:
return conditions;
}
}, {});
return Object.values(filtersObject);
};
const filterData = (filters = []) => (el) =>
mapfiltersToSets(filters).every((filterSet) =>
filterSet.some(({ key, value }) => el[key] === value)
);
Example:
// AC AND nonAC
data.filter(filterData([{ AC: "true" }, { nonAC: "true" }]))
Demo with extended dataset and unit tests. Good start to build from.
Related Topics
In Swift, Does Resetting the Property Inside Didset Trigger Another Didset
Use of Undeclared Type 'Viewcontroller' When Unit Testing My Own Viewcontroller in Swift
Firebase Query Containing Value
How to Use .Svg Images in Swiftui
Convert Firdatasnapshot to Custom Type
Differences Between "Static Var" and "Var" in Swift
When Should I Use Optionals and When Should I Use Non-Optionals with Default Values
Type Ccc Doesnt Conform to Protocol 'Nsobjectprotocol'
Testing an Executable with Swift
Clearing Uiwebview's Cache in Swift
Binary Operator '===' Cannot Be Applied to Operands of Type 'Any' and 'Uibarbuttonitem!'
Converting .M4A File to .Aiff Using Audioconverter Swift
Open a Viewcontroller from Remote Notification
Convert Float Value to String in Swift