Filtering Multiple Items With Es6 Array Functions

How to filter an array/object by checking multiple values

You can use .filter() method of the Array object:

var filtered = workItems.filter(function(element) {
// Create an array using `.split()` method
var cats = element.category.split(' ');

// Filter the returned array based on specified filters
// If the length of the returned filtered array is equal to
// length of the filters array the element should be returned
return cats.filter(function(cat) {
return filtersArray.indexOf(cat) > -1;
}).length === filtersArray.length;
});

http://jsfiddle.net/6RBnB/

Some old browsers like IE8 doesn't support .filter() method of the Array object, if you are using jQuery you can use .filter() method of jQuery object.

jQuery version:

var filtered = $(workItems).filter(function(i, element) {
var cats = element.category.split(' ');

return $(cats).filter(function(_, cat) {
return $.inArray(cat, filtersArray) > -1;
}).length === filtersArray.length;
});

how to filter multiple values from an array in javascript

You can store names that needs to be filters in an array and then check if name exists in array or not

eg.

var arr = [
{name: "bobby", id: 1, age: 23},
{name: "charls", id: 2, age: 28},
{name: "indi", id: 3, age: 23},
{name: "charlie", id: 4, age: 25}
]
const names = ["bobby", "indi"];

const filtered = arr.filter((item)=>{
return names.includes(item.name)
});

console.log(filtered)

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 based on multiple filters

Since you want to be able to not just match specific key-value pairs, but may also need to do stuff like pre-processing of the value before filtering (like you do with converting email to lower case), then a generic approach might work best for you. You can have something like this

const updateFilter = () => {
const filteredInvoices = invoices.filter(invoice => {
let validInvoice = true;

for (const [key, value] of Object.entries(filter)) {
if (Array.isArray(value)) {
if (!value.includes(invoice[key])) {
validInvoice = false;
}
}
else if (typeof value === 'function') {
if (!value(invoice[key])) {
validInvoice = false;
}
}
else {
if (value !== invoice[key]) validInvoice = false;
}
}

return validInvoice;
});

setListToRender(filteredInvoices)
}

With this approach, you can have a filter that has either raw values, functions or arrays. Like so:

const filter = {
// This will check if the invoice 'active' property is true
active: true,
// This will check that the status is NOT equal to pending
status: (status) => status !== 'pending',
// This will check if the email matches ANY of these values
email: ['john@doe.com', 'cho@mumma.com']
};

This approach allows more nuance than the simple key/value matching approach, and can let you customise your filters more deeply

filter array of data multiple values javascript

You could get the values from the object and check if all values of the query is in the values array.

const
filter = (data, query) => data.filter(o => {
const values = Object.values(o);
return query.every(q => values.includes(q));
}),
products = [{ name: 'A', color: 'Blue', size: 50, locations: 'USA' }, { name: 'B', color: 'Blue', size: 60, locations: 'Europe' }, { name: 'C', color: 'Blue', size: 30, locations: 'Europe' }, { name: 'D', color: 'Black', size: 70, locations: 'Japan' }, { name: 'E', color: 'Green', size: 50, locations: 'Europe' }, { name: 'F', color: 'Blue', size: 50, locations: 'Brazil' }, { name: 'G', color: 'Black', size: 40, locations: 'Australia' }];

console.log(filter(products, ['Blue']));
console.log(filter(products, ['Blue', 'Europe']));
console.log(filter(products, ['Black']));
console.log(filter(products, ['Black', 'Japan']));
console.log(filter(products, [['Blue', 'Green']]));
.as-console-wrapper { max-height: 100% !important; top: 0; }

Filtering an array with multiple filter arrays

You can create the array of values of selectedFilters as well array of filters property values. Then use every on selectedFilters to check if all values in it are present within the filters.

const selectedFilters = {    color: ["Red", "Blue"],    type: ["Shirt"],    size: ["M"]};
const items = [ { name: "Item 1", filters: { color: ["Red", "Blue", "Black"], type: ["Shirt"], size: ["M"] } }, { name: "Item 2", filters: { color: ["Red"], type: ["Pants"], size: ["M"] } }];
const filterArr = Object.values(selectedFilters).flat();
const output = items.filter(({filters}) => { const objFilters = Object.values(filters).flat(); return filterArr.every(val => objFilters.includes(val));})console.log(output);

Filter an array of objects using the filter method with multiple tests

Try:

articles.filter(article => 
Object.values(article).every(x => (x !== null))
&& article.title.length <= 90
)

Let's break this down:

articles.filter(article => ...) 

.filter is a function property of type that accepts a callback argument, which it calls for each item. Essentially, we're passing it a function - not executing it right away, which it can call at its leisure. It's sort of like:

let a = alert;

We're not calling the alert function, we're just saving it to a variable. In the case of .filter, we're using it as a pseudo-variable - an argument. Internally, all .filter is doing is:

Array.prototype.filter(callbackFunc) {
newArr = [];
for (i=0;i<this.length;i++){
if (callbackFunc(this[i]) === false){ // We're calling `callbackFunc` manually, for each item in the loop.
newArr.push(this[i]);
}
}

return newArr;
}

The next bit to explain is the actual callback function we're using. It's defined with ES6 arrow syntax, but it's the equivalent of:

articles.filter(function(article){
return Object.values(article).every(x => (x !== null))
&& article.title.length <= 90
})

The first line of the callback function, Object.values(article).every(x => (x !== null)), can be broken down to:

let values = Object.values(article); // Get the value of all of the keys in the object

function checkFunction(item){ // Define a helper function
return (x !== null); // Which returns if an item is _not_ null.
}

let result = values.every(checkFunction); // Run `checkFunction` on every item in the array (see below), and ensure it matches _all_ of them.

Finally, we just need to clarify what every does. It's another example of functional JS, where functions accept callback functions as parameters. The internal code looks like this:

Array.prototype.every(callbackFunc) {
for (i=0;i<this.length;i++){
if (callbackFunc(this[i]) === false){ // We're calling `callbackFunc` manually, for each item in the loop.
return false;
}
}
// In JS, returning a value automatically stops execution of the function.
// So this line of code is only reached if `return false` is never met.
return true;
}

And && article.title.length <= 90 should hopefully be self-explanatory: while .every returns a boolean value (true or false), a true will only be returned by the callback function to the filter if the second condition is also met, i.e if the every returns true and article.title.length <= 90



Related Topics



Leave a reply



Submit