JavaScript filtre tableau plusieurs conditions
Je veux simplifier un tableau d'objets. Supposons que j'ai le tableau suivant:
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'
}];
Et filtre objet:
var filter = {address: 'England', name: 'Mark'};
Par exemple, j'ai besoin de filtrer tous les utilisateurs par adresse et nom, donc je fais une boucle dans les propriétés de l'objet de filtre et je le vérifie:
function filterUsers (users, filter) {
var result = [];
for (var prop in filter) {
if (filter.hasOwnProperty(prop)) {
//at the first iteration prop will be address
for (var i = 0; i < filter.length; i++) {
if (users[i][prop] === filter[prop]) {
result.push(users[i]);
}
}
}
}
return result;
}
Donc lors de la première itération quand {[3] } sera égal 'England'
deux utilisateurs seront ajoutés au résultat du tableau (avec le nom Tom et Mark), mais lors de la deuxième itération quand {[5] } sera égal Mark
seul le dernier utilisateur devrait être ajouté au résultat du tableau, mais je me retrouve avec deux éléments dans le tableau.
J'ai une petite idée de pourquoi cela se passe-t-il mais toujours coincé dessus et n'a pas pu trouver une bonne solution pour le réparer. Toute aide est appréciable. Grâce.
7 réponses
, Vous pouvez faire comme ceci
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)
Une autre prise pour ceux d'entre vous qui aiment le code succinct.
NOTE : la méthode FILTER peut prendre un argument supplémentaire this, puis en utilisant une fonction de flèche E6, nous pouvons réutiliser le bon this pour obtenir un bon one-liner.
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'}];
var query = {address: "England", name: "Mark"};
var result = users.filter(search, query);
function search(user){
return Object.keys(this).every((key) => user[key] === this[key]);
}
// |----------------------- Code for displaying results -----------------|
var element = document.getElementById('result');
function createMarkUp(data){
Object.keys(query).forEach(function(key){
var p = document.createElement('p');
p.appendChild(document.createTextNode(
key.toUpperCase() + ': ' + result[0][key]));
element.appendChild(p);
});
}
createMarkUp(result);
<div id="result"></div>
Vous pouvez le faire dans une ligne
users = users.filter(obj => obj.name == filter.name && obj.address == filter.address)
Je pense que cela pourrait aider.
const filters = ['a', 'b'];
const results = [
{
name: 'Result 1',
category: ['a']
},
{
name: 'Result 2',
category: ['a', 'b']
},
{
name: 'Result 3',
category: ['c', 'a', 'b', 'd']
}
];
const filteredResults = results.filter(item =>
filters
.map(val => item.category.indexOf(val))
.map(val => (val > -1 ? true : false))
.reduce((acc, cum) => acc && cum)
);
console.log(filteredResults);
Peut également être fait de cette façon:
this.users = this.users.filter((item) => {
return (item.name.toString().toLowerCase().indexOf(val.toLowerCase()) > -1 ||
item.address.toLowerCase().indexOf(val.toLowerCase()) > -1 ||
item.age.toLowerCase().indexOf(val.toLowerCase()) > -1 ||
item.email.toLowerCase().indexOf(val.toLowerCase()) > -1);
})
Si la finalité de votre code est d'obtenir l'utilisateur filtré, j'inverserais le for
pour évaluer le user
au lieu de réduire le tableau de résultats à chaque itération.
Voici un exemple (non testé):
function filterUsers (users, filter) {
var result = [];
for (i=0;i<users.length;i++){
for (var prop in filter) {
if (users.hasOwnProperty(prop) && users[i][prop] === filter[prop]) {
result.push(users[i]);
}
}
}
return result;
}
Voici la version ES6 de l'utilisation de la fonction flèche dans le filtre. Poster ceci comme une réponse parce que la plupart d'entre nous utilisent ES6 ces jours-ci et peuvent aider les lecteurs à filtrer de manière avancée en utilisant la fonction arrow, let et const.
const filter = {
address: 'England',
name: 'Mark'
};
let 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(item => {
for (let key in filter) {
if (item[key] === undefined || item[key] != filter[key])
return false;
}
return true;
});
console.log(users)