0

I have an array of objects that I want to filter for a string. So I want to check multiple properties if they contain the filter string (case insensitive).

Here's the array:

[{
  id: "01234", 
  name: "My Object 01234", 
  short_name: "MO01234"
}, ...]

So all of the following filter strings should match that object: 0123, obj, mO01 etc.

Here's what I have right now:

const filterString = this.filterString.toLowerCase();
return myObjects.filter(
  entry => {
    return 
      entry.id.toLowerCase().indexOf(filterString) >= 0 || 
      entry.name.toLowerCase().indexOf(filterString) >= 0 ||    
      entry.short_name.toLowerCase().indexOf(filterString) >= 0;
  }
);

Can you think of a faster/cleaner way to do that?

Androidicus
  • 1,688
  • 4
  • 24
  • 36
  • 3
    Please read [What is the difference between JSON and Object Literal Notation?](https://stackoverflow.com/questions/2904131/what-is-the-difference-between-json-and-object-literal-notation) – str Apr 24 '18 at 08:53

3 Answers3

1

I don't think that you can do it faster, but cleaner may be something like that

const filterString = this.filterString.toLowerCase();
return myObjects.filter((entry) => {
    return Object.values(entry).some((value) => {
        return value.toLowerCase().includes(filterString)
    })
});
ilsotov
  • 162
  • 1
  • 9
0

If you are allowed to put additional properties in your object, perhaps you could concatenate id, name and short_name (already in lowercase) into a single string and store it in the object as e.g. search_key; then you'd only have to check that.

{
  id: "01234", 
  name: "My Object 01234", 
  short_name: "MO01234",
  search_key: "01234:my object 01234:mo01234"
}

return myObjects.filter(
  entry => entry.search_key.indexOf(filterString) >= 0
);

One thing you have to be mindful of in this case is to prevent unintended matches that may arise because e.g. the last few characters of id and the first few characters of name together produce a match. This is why I used a : delimiter here, assuming that's a character that can't appear in an ID or a short name.

Máté Safranka
  • 4,081
  • 1
  • 10
  • 22
0

let objects = [{
    id: "01234", 
    name: "My Object 01234", 
    short_name: "MO01234"
},
{
    id: "test", 
    name: "test", 
    short_name: "test"
}];

const filter = (collection, searchFor) => {
    return collection.filter(obj => Object.values(obj).reduce((a,b) => a || String(b).toLowerCase().indexOf(searchFor.toLowerCase()) > -1, false))
}

console.log(filter(objects, "0123"));
console.log(filter(objects, "obj"));
console.log(filter(objects, "mO01"));

You could also extend this function to take a set of columns as parameter to filter on.

Another version using Regex:

const filterRegex = (collection, searchFor) => {
    return collection.filter(obj => Object.values(obj).reduce((a,b) => a || String(b).match(new RegExp(searchFor, 'gi')), false))
}


console.log(filterRegex(objects, "0123"));
console.log(filterRegex(objects, "obj"));
console.log(filterRegex(objects, "mO01"));
Jan Wendland
  • 1,350
  • 9
  • 17