Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to multi filter an array of objects?

This is my demo code:

//Imports and decorators up here for Angular 2

export class ProductsListComponent {

  products = [
    { name: "A", color: "Blue", size: 50 },
    { name: "B", color: "Blue", size: 60 },
    { name: "C", color: "Black", size: 70 }
  ];

  filters = {
    colors: ["Blue", "Black"],
    sizes: [70, 50]
  };

  //This is my first approach but just works for the colors array inside filters object  
  //and i have no ideia how to filter sizes too
  filterProducts() {
    let results = [];
    this.filters.colors.forEach((color) => {
      this.products.filter((product) => {
        if (product.color === color) {
          results.push(product);
        }
        return true; //filter callback requires a boolean
      })
    });
    console.log(results);
  }

}

I would like the results array would look like this according to filters:

var results = [
  { "name": "A", "color": "Blue", "size": 50 },
  { "name": "C", "color": "Black", "size": 70 }
];

I hope to have explained my problem well.

like image 792
Elkin Avatar asked Sep 28 '16 20:09

Elkin


People also ask

Can you filter an array of objects?

One can use filter() function in JavaScript to filter the object array based on attributes. The filter() function will return a new array containing all the array elements that pass the given condition. If no elements pass the condition it returns an empty array.

How do you filter an array of numbers?

Use the filter() method to filter an array to only numbers, e.g. arr. filter(value => typeof value === 'number') . The filter method returns an array with all the elements that satisfy the condition. In our case, all array elements with a type of number .


2 Answers

here's an example using every and some array methods:

var products=[
    {"name":"A","color":"Blue","size":50},
    {"name":"B","color":"Blue","size":60},
    {"name":"C","color":"Black","size":70}
    ];

var filters={
    color:["Blue","Black"],
    size:[70,50]
    };
var r = products.filter(x =>
        Object.keys(filters).every(f => 
        filters[f].some( z => z == x[f] )))

console.log(r)
like image 124
maioman Avatar answered Sep 28 '22 09:09

maioman


You could rewrite function to following

filterProducts(){
    let results=[], filersCopy = angular.copy(this.filters.colors);
    this.products.filter((product)=>{
       //checking in filters.colors collection using indexOf
       let index = filersCopy.indexOf(product.color);
       if(index > -1){
          //removing matched element from copy, to ensure single occurence
          filersCopy.splice(index, 1); 
          results.push(product);
          return true;
       }
    });
    console.log(results); //Printing filtered results
}
like image 44
Pankaj Parkar Avatar answered Sep 28 '22 08:09

Pankaj Parkar