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?
-
5provide a [mcve] along with an example of search string and the JSON itself. – zer00ne Dec 05 '17 at 12:49
-
1Does this answer your question? [JS search in object values](https://stackoverflow.com/questions/8517089/js-search-in-object-values) – Heretic Monkey Aug 11 '21 at 13:24
8 Answers
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.

- 42,689
- 17
- 109
- 127
-
-
-
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
-
dont forget to check the value using typeof === 'string' – Alauddin Afif Cassandra Jul 18 '23 at 15:35
Works like a charm:
data.filter((obj) =>
JSON.stringify(obj).toLowerCase().includes(query.toLowerCase())
)
-
1This will also check if the keys of the object contains the `query`. – Heretic Monkey Aug 11 '21 at 13:23
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);

- 3,091
- 1
- 17
- 27
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;
});

- 175
- 6
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 ) )

- 1,303
- 2
- 21
- 36
I found out a method that works for me. I went further to convert the query string to lower case:
const data = [
{a: 'ekom', b: 'obong'},
{a: 'fin', b: 'barr'}
];
const queryString = 'fi';
const result = data.filter((obj) => JSON.stringify(obj).toLowerCase().includes(queryString.toString().toLowerCase()));
console.log('Result: ', result);

- 41
- 3
A little improvement to str's answer, for better performance;
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.indexOf(search) >= 0));
console.log(res);

- 19
- 1
- 1
Thanks, @str to contribute. I just update it a little bit because it's not working a newer version of js is in strict mode. We need to covert the final val
to string before checking includes
method.
const arr = [
{a: 'abcd', b: 'cdaf'},
{a: 'xyz', b: 'axcfd'}
];
const searchValue = 'a';
const newArr = arr.filter(obj => Object.values(obj).some(val => val.toString().includes(searchValue)));

- 460
- 4
- 8