web-dev-qa-db-fra.com

Comment filtrer un tableau / objet en vérifiant plusieurs valeurs

Je joue avec des tableaux en essayant de mieux les comprendre car j'ai tendance à travailler avec eux dernièrement. J'ai eu ce cas où je veux rechercher un tableau et comparer ses valeurs d'élément à un autre tableau qui contient les valeurs de certains filtres sélectionnés.

Par exemple, si je sélectionne 3 filtres, je veux plus tard écrire des correspondances dans un nouveau tableau - uniquement celles qui correspondent aux 3 filtres.

Pour une meilleure compréhension, j'ai mis en place un exemple sur http://jsfiddle.net/easwee/x8U4v/36/

Le code est:

var workItems =   [
    { "id": 2616, "category": ".category-copy .category-beauty .category-fashion"}, //this is a match
    { "id": 1505, "category": ".category-beauty"}, // NOT
    { "id": 1500, "category": ".category-beauty .category-fashion"}, // NOT
    { "id": 692, "category": ".category-stills .category-retouching"}, // NOT
    { "id": 593, "category": ".category-beauty .category-capture .category-fashion .category-product .category-stills .category-stills-retouching "}, // NOT
    { "id": 636, "category": ".category-beauty .category-copy .category-fashion"}, //this is a match
    { "id": 547, "category": ".category-fashion .category-lifestyle .category-stills .category-stills-retouching "}, // NOT
    { "id": 588, "category": ".category-capture .category-recent-work .category-copy .category-beauty .category-fashion"} //this is a match
];

var filtersArray = [".category-beauty", ".category-fashion", ".category-copy"];

var i;
for (i = 0; i < filtersArray.length; ++i) {
    var searchString = filtersArray[i];
    console.log('Searching for: ' + searchString);
    var filtered = $(workItems).filter(function(){
        return this.category.indexOf(searchString);
    });    
}   
console.log('Filtered results: ' + JSON.stringify(filtered, null, 4));

J'ai aussi essayé avec

filtered = $.grep(workItems, function(element, index){
    return element.category.indexOf(filtersArray[i]); 
}, true);

mais il ne correspond qu'au premier filtre et seulement s'il est au début de workItems.category

J'ai essayé de nombreuses solutions différentes mais je ne peux pas vraiment faire fonctionner cela. Quelle fonction dois-je utiliser pour retourner le résultat souhaité?

20
easwee

Vous pouvez utiliser la méthode .filter() de l'objet Array:

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/

Certains anciens navigateurs comme IE8 ne prennent pas en charge la méthode .filter() de l'objet Array, si vous utilisez jQuery, vous pouvez utiliser la méthode .filter() de l'objet jQuery.

version jQuery:

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;
});
18
undefined

Vous pouvez utiliser .filter () avec les opérateurs booléens ie &&:

 var find = my_array.filter(function(result) {
       return result.param1 === "srting1" && result.param2 === 'string2';
       });
    return find[0];
 }
5
aabiro
2
chrisarton