Filter array of objects whose any properties contains a value

后端 未结 8 1095
你的背包
你的背包 2020-12-13 19:26

I\'m wondering what is the cleanest way, better way to filter an array of objects depending on a string keyword. The search has to be made in any properties of

8条回答
  •  情歌与酒
    2020-12-13 19:45

    This code checks all the nested values until it finds what it's looking for, then stops and returns true to the "array.filter" for the object it was searching inside(unless it can't find anything - returns false). When true is returned, the object is added to the array that the "array.filter" method returns.

    const data = [{
        a: "a",
        b: {
          c: "c",
          d: {
            e: "e",
            f: [
              "g",
              {
                i: "i",
                j: {},
                k: []
              }
            ]
          }
        }
      },
      {
        a: "a",
        b: {
          c: "c",
          d: {
            e: "e",
            f: [
              "g",
              {
                i: "findme",
                j: {},
                k: []
              }
            ]
          }
        }
      },
      {
        a: "a",
        b: {
          c: "c",
          d: {
            e: "e",
            f: [
              "g",
              {
                i: "i",
                j: {},
                k: []
              }
            ]
          }
        }
      }
    ];
    
    function getState(data: any, inputValue: string, state = false) {
      for (const value of Object.values(data)) {
        if (typeof value === 'object' && value !== null && Object.keys(value).length > 0 && state === false) {
          state = getState(value, inputValue, state);
        } else {
          if (state === false) {
            state = JSON.stringify(value).toLowerCase().includes(inputValue.toLowerCase());
          } else {
            return state;
          }
        }
      }
      return state;
    }
    
    function filter(data: [], inputValue) {
      return data.filter((element) => getState(element, inputValue));
    }
    
    console.log(filter(data, 'findme'));

    If you need to search for objects that contain multiple keywords, to narrow down the filtered objects further, which makes the filter even more user friendly.

    const data = [{
        a: "a",
        b: {
          c: "c",
          d: {
            e: "findme2",
            f: [
              "g",
              {
                i: "i",
                j: {},
                k: []
              }
            ]
          }
        }
      },
      {
        a: "a",
        b: {
          c: "c",
          d: {
            e: "e",
            f: [
              "g",
              {
                i: "findme",
                j: {},
                k: []
              }
            ]
          }
        }
      },
      {
        a: "a",
        b: {
          c: "c",
          d: {
            e: "findme2",
            f: [
              "g",
              {
                i: "findme",
                j: {},
                k: []
              }
            ]
          }
        }
      }
    ];
    
    function filter(data: [], inputValue: string) {
      return data.filter((element) => checkState(element, inputValue));
    }
    
    function checkState(element: any, inputValue: string) {
      const filterValues = inputValue.trim().split(' ');
      const states: boolean[] = [];
    
      for (let index = 0; index < filterValues.length; index++) {
        states[index] = getState(element, filterValues[index]);
      }
    
      return states.every(state => state === true);
    }
    
    function getState(data: any, inputValue: string, state = false) {
      for (const value of Object.values(data)) {
        if (typeof value === 'object' && value !== null && Object.keys(value).length > 0 && state === false) {
          state = getState(value, inputValue, state);
        } else {
          if (state === false) {
            state = JSON.stringify(value).toLowerCase().includes(inputValue.toLowerCase());
          } else {
            return state;
          }
        }
      }
      return state;
    }
    
    console.log(filter(data, 'findme')); // gets all objects that contain "findme"
    
    console.log(filter(data, 'findme findme2')); // gets all objects that contain "findme" and "findme2"

提交回复
热议问题