Home > Blockchain >  Filtering js array of objects based on more than one property
Filtering js array of objects based on more than one property

Time:12-30

(using react js) I'm trying to filter this array :

[
  {gov:"A1", district:"1" , town:"t1", type:"cars factory"},
  {gov:"A2", district:"2" , town:"t2", type:"farm"},
  {gov:"A1", district:"1" , town:"t1", type:"milk factory"},
  {gov:"A1", district:"4" , town:"t3", type:"milk factory"},
  {gov:"A3", district:"3" , town:"t4", type:"medicine factory"},
  {gov:"A4", district:"6" , town:"t5", type:"food"},
  {gov:"A3", district:"7" , town:"t4", type:"milk factory"},
  {gov:"A2", district:"2" , town:"t7", type:"construction"},
]

let's say this array is called Locations, I need to implement 4 filters, the first filter is filtering using gov (governorates) , second filter is using districts , third using towns, lastly using type of industry. But what if I already chose filter by districts then I want to filter the type of industry inside this district, I need to do it dynamically; such, I implemented 4 select inputs (gov, district, town , type) , I could have always filtered the original array, but this will return for example the milk factories in all the govs all the time ,instead of a specific govs. So what I need, is to filter based on more than one attribute or property and not by just writing it statically

newArray=Locations.filter( (e)=>{ return e.gov=='A1' && e.type='milk factory'}) 

this solves it but not all the time since I might also choose to filter milk factories on a specific district , town , or even in the whole country (on the parent array)

let's assume that

gov \\is the value of the selection of governorates
district \\is the value of the selection of districts
town \\is the value of the selection of towns
type \\is the value of the selection of the type

btw, I'm using react leaflet map to display these values on markers, that's why I need to filter.

So I figured out to post it here , maybe a kind soul would help me solving it Thank you guys

CodePudding user response:

You use can the following approach. The idea is to have all filters in one matching object, and then call filterData any time you change the matchObj :)

const data = [
  {gov:"A1", district:"1" , town:"t1", type:"cars factory"},
  {gov:"A2", district:"2" , town:"t2", type:"farm"},
  {gov:"A1", district:"1" , town:"t1", type:"milk factory"},
  {gov:"A1", district:"4" , town:"t3", type:"milk factory"},
  {gov:"A3", district:"3" , town:"t4", type:"medicine factory"},
  {gov:"A4", district:"6" , town:"t5", type:"food"},
  {gov:"A3", district:"7" , town:"t4", type:"milk factory"},
  {gov:"A2", district:"2" , town:"t7", type:"construction"},
];

const filterData = (matchObj) => {
  const matchEntries = Object.entries(matchObj);
  return data.filter(item => {
    return matchEntries.every(([key, val]) => item[key] === val);
  });
};


// Tests:
const matchObj1 = { gov:"A1" };
console.log(matchObj1, filterData(matchObj1));

const matchObj2 = { gov:"A1", type: "milk factory" };
console.log(matchObj2, filterData(matchObj2));

const matchObj3 = { gov:"A1", type: "milk factory", town: "t3" };
console.log(matchObj3, filterData(matchObj3));
  

CodePudding user response:

I think you can implement your filter with criteria like this code example

  • Related