简体   繁体   中英

Javascript: Filter an array of objects on multiple values

I'm trying to filter a grid using multiple filters of various types (boolean, string match, etc.). The grid is just a JSON array. I have to filter every time a filter value is set or removed (ie a checkbox is checked, or unchecked). I was trying to do this using a very complex switch statement, but then I found this post by @ori-drori which explains how to do this using a much simpler map of filterHandlers. However, when I run this code I don't get the desired results and I'm stumped as to why. Here's what I've got:

filterGrid(rows) {
   const filterList = [
     { 'open': this.onlyOpen },
     { 'assmtComplete': this.onlyAssmtCompleted },
     { 'bureau': this.selectedBureau ? this.selectedBureau : '' },
     { 'unit': this.selectedUnit ? this.selectedUnit : '' }
   ];
   const filterHandlers = new Map([
     [
      'open',
      (ref) => !ref.cwsClosureReasonDescription
     ],
     [
      'assmtComplete',
      (ref) => ref.safetyAsstComplDate !== null
     ],
     [ 
      'bureau', 
      (ref, val) => ref.bureauCode === val 
     ],
     [ 
      'unit', 
      (ref, val) => ref.unitID === val 
     ],
   ]);

   const applyFilters = (arr, filters) => {
      const filterKeys = Object.keys(filters);  
      return arr.filter(o => filterKeys.every((key) => {
        const handler = filterHandlers.get(key);  // THIS returns undefined every time
        return !handler || handler(o[key], filters[key]);
      }));
   };

   const result = applyFilters(rows, filterList);
   console.log(result);
 }

A sample object in the "rows" might look like this:

{
   createdDate: "2019-10-18T10:56:43.477"
   closureReasonDescription: null
   refNumber: "1231-3213-2132-1321321"
   incidentZipCode: "92108"
   intakeDate: "2019-10-19T00:56:24.953"
   referralId: 1461
   bureauCode: "S"
   unitID: 1017
   safetyAsstComplDate: null
   taskTypeId: null
}

As you can see from the comment in the code above, that line in the applyFilters is always undefined. I've tried a few ways of getting the handler from that, but I'm not sure what key is supposed to be - an integer or a string? Any tips would be GREATLY appreciated!

filterKeys (defined by Object.keys(filterList) ) is an array of numeric keys ( ["0", "1", "2", "3"] ) since filterList is an array whose keys are numeric indices.

I think you want filterKeys to be the keys of each object in the filterList array. This could be achieved most easily by making filterList a single object, with many keys, instead of an array of objects with one key each:

const filterList = {
    'open': this.onlyOpen,
    'assmtComplete': this.onlyAssmtCompleted,
    'bureau': this.selectedBureau ? this.selectedBureau : '',
    'unit': this.selectedUnit ? this.selectedUnit : ''
];

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM