Nakos Kotsanis
Nakos Kotsanis

Reputation: 300

Filter array with JSONS with more than one conditions in javascript

I have the following array

 let tableA=[{id:'1', name:'name1',age:'31',gender:'male',class='B'},
             {id:'2', name:'name2',age:'38',gender:'male',class='A'},
             {id:'3', name:'name3',age:'35',gender:'male',class='C'},
             {id:'4', name:'name4',age:'20',gender:'female',class='B'},
             {id:'5', name:'name5',age:'19',gender:'female',class='A'},
             {id:'6', name:'name6',age:'31',gender:'male',class='A'}
            ];

and this array for filters

 let filters = [{type:'gender',value:"male"}, {type:'age',value:"31"}];

I'm trying to filter tableA with the values of table filters, all filters must match. Filters are not static, it means that filters can include json files for all table keys.

So far I'm trying to filter table_A with the code above.

 let filtered_table=[];
 tableA.forEach(row => {
    filters.map((item) => {
        if(row[item.type]==item.value){
           filtered_table.push(row);
         }
     });
});
console.log(filtered_table);

the result of the code above is:

 [ { id: '1', name: 'name1', age: '31', gender: 'male', class: 'B' },
   { id: '1', name: 'name1', age: '31', gender: 'male', class: 'B' },
   { id: '2', name: 'name2', age: '38', gender: 'male', class: 'A' },
   { id: '3', name: 'name3', age: '35', gender: 'male', class: 'C' },
   { id: '6', name: 'name6', age: '31', gender: 'male', class: 'A' },
   { id: '6', name: 'name6', age: '31', gender: 'male', class: 'A' } ]

How I can get back only the row that match for all of the filters_table items combined? For this example I'm expecting this:

[ { id: '1', name: 'name1', age: '31', gender: 'male', class: 'B' },
  { id: '6', name: 'name6', age: '31', gender: 'male', class: 'A' } ]

Upvotes: 2

Views: 44

Answers (3)

Harrison
Harrison

Reputation: 2347

The thing you're after is the .every method See Docs.

var filters = [
  { type: "gender", value: "male" },
  { type: "age", value: "31" },
];


var tableA = [
  { id: "1", name: "name1", age: "31", gender: "male", class: "B" },
  { id: "2", name: "name2", age: "38", gender: "male", class: "A" },
  { id: "3", name: "name3", age: "35", gender: "male", class: "C" },
  { id: "4", name: "name4", age: "20", gender: "female", class: "B" },
  { id: "5", name: "name5", age: "19", gender: "female", class: "A" },
  { id: "6", name: "name6", age: "31", gender: "male", class: "A" },
]

var result = tableA.filter(item =>
  filters.every(filter => item[filter.type] === filter.value)
);

console.log(result)

//  [ { id: '1', name: 'name1', age: '31', gender: 'male', class: 'B' },
//    { id: '6', name: 'name6', age: '31', gender: 'male', class: 'A' } ]

Below is a more verbose way, not using the ES6 Syntax:

var result tableA.filter(item => {
  //ensure every filter has been matched against
  var everyFilterMatched = filters.every(filter => {
    return item[filter.type] === filter.value;
  });
  return everyFilterMatched
});

N.B: Edit is use every as I am assuming you may not know how many filters you will have, just that there is an array of the given shape, and you want to match *all of them.

Upvotes: 1

Kopi Bryant
Kopi Bryant

Reputation: 1366

Its simple with js .filter(). Check this out Its looping every element in tableA and filter out the gender and the age

 let tableA = [{
     id: '1',
     name: 'name1',
     age: '31',
     gender: 'male',
     class: 'B'
   },
   {
     id: '2',
     name: 'name2',
     age: '38',
     gender: 'male',
     class: 'A'
   },
   {
     id: '3',
     name: 'name3',
     age: '35',
     gender: 'male',
     class: 'C'
   },
   {
     id: '4',
     name: 'name4',
     age: '20',
     gender: 'female',
     class: 'B'
   },
   {
     id: '5',
     name: 'name5',
     age: '19',
     gender: 'female',
     class: 'A'
   },
   {
     id: '6',
     name: 'name6',
     age: '31',
     gender: 'male',
     class: 'A'
   }
 ];
 
 let fil = [{
   type: 'gender',
   value: "male"
 }, {
   type: 'age',
   value: "31"
 }];


const data = tableA.filter((ele,index) => {
    return ele.gender == fil[0].value && ele.age == fil[1].value
})

console.log(data)

Upvotes: 1

Ivan124
Ivan124

Reputation: 160


let filtered_table=[];
 tableA.forEach(row => {
    const flag = filters.map((item) => {
        if(row[item.type]==item.value){
           return 1;
         } else {
           return 0;
         }
     });
     if(flag.filter(el=>el != 1).length==0) {
        filtered_table.push(row);   
     }
});
console.log(filtered_table);

Upvotes: 3

Related Questions