2
\$\begingroup\$

I am not a JS/TS Guru, so i wanted to ask if one could write this better.

I needed a very primitive Full-Text-Search of some properties of an Object. What do you think?

export const search = <T, K extends keyof T>(term: string, objects: T[], keys: K[]): T[] => {
  const foundObjects = objects.filter(x => {
    for (const key of keys) {
      if (x.hasOwnProperty(key) === false) {
        continue;
      }

      const val = x[key];

      if (typeof val === 'string' && val.toLowerCase().includes(term)) {
        return true;
      } else {
        continue;
      }
    }
    return false;
  });
  return foundObjects;
};
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

You have a lot of code that is not needed.

  • The two continue are not needed.

  • Rather than assign the variable foundObjects the filtered result just return the result directly.

  • The variable val that holds the property can be side stepped.
  • Then the hasOwnProperty can be combined with the if statement
  • Rather than use the for loop you can also use Array.some to find if any item matches the search

Thus you get

export const search = <T, K extends keyof T>(term: string, objects: T[], keys: K[]): T[] => {
    return objects.filter(x => 
        keys.some(key => 
            x.hasOwnProperty(key) && 
            typeof x[key] === 'string' && 
            x[key].toLowerCase().includes(term)
        )
    );
};
\$\endgroup\$
1
  • \$\begingroup\$ Thx. I learned something new. One small issue with your solution. (I had the same thats why this val variable is there). x[key].toLowerCase() throws a Property 'toLowerCase' does not exist on type 'T[K]' error. I know its a TS issue, but thats the only small "issue". Thx again. \$\endgroup\$
    – VSDekar
    Apr 23, 2019 at 21:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.