2

I have an array of JSON objects. Given a search string, I want to filter the array for only those objects which have that string as a substring of one of their properties. How do I do this efficiently?

Boris K
  • 3,088
  • 8
  • 43
  • 78

5 Answers5

11

Assuming you want to find the substring in the property value, you can use the following code:

const arr = [
  {a:'abc', b:'efg', c:'hij'},
  {a:'abc', b:'efg', c:'hij'},
  {a:'123', b:'456', c:'789'},
];

const search = 'a';

const res = arr.filter(obj => Object.values(obj).some(val => val.includes(search)));

console.log(res);

If you want to search the property name, use Object.keys instead of Object.values.

Please note that Object.values is a feature of ES2017.

str
  • 38,402
  • 15
  • 99
  • 123
  • I'm getting val.includes is not a function in chrome console. – ThomasRones Jun 17 '20 at 21:50
  • Then either you are using different code or a very old version of Chrome. – str Jun 18 '20 at 06:56
  • I'm also getting the same error. val.includes is not a function in chome. BTW i'm using latest version of chromeEdit: Figured out the issue. In my case, one of the object values was not a string, where this error comes up. – Shreehari Apr 29 '22 at 17:36
9

Works like a charm:

data.filter((obj) =>
  JSON.stringify(obj).toLowerCase().includes(query.toLowerCase())
)
cela
  • 2,190
  • 3
  • 21
  • 40
sandstorm
  • 117
  • 3
  • 7
2

Maybe you want to do something like this:

var list = [
    {var1: "value1", var2: "value2", var3: "value3"},
    {var1: "value4", var2: "value5", var3: "value6"},
    {var1: "value4", var2: "value3", var3: "value2"},
    {var1: "value2", var2: "value8", var3: "value6"},
    {var1: "value1", var2: "value7", var3: "value7"},
    {var1: "value1", var2: "value6", var3: "value2"},
];

var searchString = "value2";

var newList = list.filter(element => {
    for (var property in element) {
        if (element.hasOwnProperty(property)) {
            if(element[property] == searchString) {
                return true;
            }
        }
    }
});

console.log(newList);
David Vicente
  • 2,981
  • 1
  • 16
  • 27
2

You could use the filter method to filter the array and then use the Object.keys function to get an array of keys on the current object. You can then loop over each key and check if it has the substring (I added some guards to protect against calling .indexOf on an identifier without that method.)

const search = 'xyz';
const data = yourDataFunction();
const filteredData = data.filter(item => {
  let found = false;
  Object.keys(item).forEach(key => {
    if (item[key] && item[key].indexOf && item[key].indexOf(search) > -1) {
      found = true;
    }
  });
  return found;
});
John Rodney
  • 175
  • 6
1
var myStr = 'abc';
var myArr = [{abc:1,def:2}, {ghi:1,jkl:2}];
myArr.filter( obj => Object.keys(obj).some( key => key.indexOf(myStr) > -1 ) )
stackoverflow
  • 715
  • 1
  • 17
  • 31