Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JS search in object values

I have an array of homogeneous objects like so;

[
  {
    "foo" : "bar",
    "bar" : "sit"
  },
  {
    "foo" : "lorem",
    "bar" : "ipsum"
  },
  {
    "foo" : "dolor",
    "bar" : "amet"
  }
]

I'd like to search these objects' values (not keys) with a keyword, and return an array of objects that contain the keyword in any of the values.

So for example, with a keyword r, I would get all the objects ("baR" in object #1, "loRem" in object #2 and "doloR" in object #3). With a keyword lo, I would get objects 2 and 3 ("LOrem" and "doLOr"), with a, I'd get objects 1 and 3, ("bAr" and "Amet"). With the keyword foo however, I would get an empty array, since "foo" is a key, and isn't found in any of the values (unlike "bar")... you get the idea.

How would I go about doing this? Thanks a lot in advance!

like image 567
Emphram Stavanger Avatar asked Dec 15 '11 08:12

Emphram Stavanger


People also ask

How do you find the element of an object?

Answer: Use the find() Method You can simply use the find() method to find an object by a property value in an array of objects in JavaScript. The find() method returns the first element in the given array that satisfies the provided testing function. If no values satisfy the testing function, undefined is returned.


4 Answers

Something like this:

var objects = [   {     "foo" : "bar",     "bar" : "sit"   },   {     "foo" : "lorem",     "bar" : "ipsum"   },   {     "foo" : "dolor",     "bar" : "amet"   } ];  var results = [];  var toSearch = "lo";  for(var i=0; i<objects.length; i++) {   for(key in objects[i]) {     if(objects[i][key].indexOf(toSearch)!=-1) {       results.push(objects[i]);     }   } } 

The results array will contain all matched objects.

If you search for 'lo', the result will be like:

[{ foo="lorem", bar="ipsum"}, { foo="dolor", bar="amet"}] 

NEW VERSION - Added trim code, code to ensure no duplicates in result set.

function trimString(s) {   var l=0, r=s.length -1;   while(l < s.length && s[l] == ' ') l++;   while(r > l && s[r] == ' ') r-=1;   return s.substring(l, r+1); }  function compareObjects(o1, o2) {   var k = '';   for(k in o1) if(o1[k] != o2[k]) return false;   for(k in o2) if(o1[k] != o2[k]) return false;   return true; }  function itemExists(haystack, needle) {   for(var i=0; i<haystack.length; i++) if(compareObjects(haystack[i], needle)) return true;   return false; }  var objects = [   {     "foo" : "bar",     "bar" : "sit"   },   {     "foo" : "lorem",     "bar" : "ipsum"   },   {     "foo" : "dolor blor",     "bar" : "amet blo"   } ];  function searchFor(toSearch) {   var results = [];   toSearch = trimString(toSearch); // trim it   for(var i=0; i<objects.length; i++) {     for(var key in objects[i]) {       if(objects[i][key].indexOf(toSearch)!=-1) {         if(!itemExists(results, objects[i])) results.push(objects[i]);       }     }   }   return results; }  console.log(searchFor('lo ')); 
like image 76
techfoobar Avatar answered Sep 25 '22 17:09

techfoobar


All the other old answers use a for in loop, modern JavaScript has Object.keys. Combine that with some, includes, and filter and it is a bit nicer.

var a = [{    name: 'xyz',    grade: 'x'  }, {    name: 'yaya',    grade: 'x'  }, {    name: 'x',    frade: 'd'  }, {    name: 'a',    grade: 'b'  }];    function filterIt(arr, searchKey) {    return arr.filter(function(obj) {      return Object.keys(obj).some(function(key) {        return obj[key].includes(searchKey);      })    });  }    console.log("find 'x'", filterIt(a,"x"));  console.log("find 'a'", filterIt(a,"a"));  console.log("find 'z'", filterIt(a,"z"));

Or with ES6

function filterIt(arr, searchKey) {   return arr.filter(obj => Object.keys(obj).some(key => obj[key].includes(searchKey))); } 
like image 32
epascarello Avatar answered Sep 22 '22 17:09

epascarello


This is a cool solution that works perfectly

const array = [{"title":"tile hgfgfgfh"},{"title":"Wise cool"},{"title":"titlr DEytfd ftgftgfgtgtf gtftftft"},{"title":"This is the title"},{"title":"yeah this is cool"},{"title":"tile hfyf"},{"title":"tile ehey"}];

var item = array.filter(item=>item.title.toLowerCase().includes('this'));

 alert(JSON.stringify(item))

EDITED

const array = [{"title":"tile hgfgfgfh"},{"title":"Wise cool"},{"title":"titlr DEytfd ftgftgfgtgtf gtftftft"},{"title":"This is the title"},{"title":"yeah this is cool"},{"title":"tile hfyf"},{"title":"tile ehey"}];


// array.filter loops through your array and create a new array returned as Boolean value given out "true" from eachIndex(item) function 

var item = array.filter((item)=>eachIndex(item));

//var item = array.filter();



function eachIndex(e){
console.log("Looping each index element ", e)
return e.title.toLowerCase().includes("this".toLowerCase())
}

console.log("New created array that returns \"true\" value by eachIndex ", item)
like image 23
General Omosco Avatar answered Sep 22 '22 17:09

General Omosco


This is a proposal which uses the key if given, or all properties of the object for searching a value.

function filter(array, value, key) {
    return array.filter(key
        ? a => a[key] === value
        : a => Object.keys(a).some(k => a[k] === value)
    );
}

var a = [{ name: 'xyz', grade: 'x' }, { name: 'yaya', grade: 'x' }, { name: 'x', frade: 'd' }, { name: 'a', grade: 'b' }];


console.log(filter(a, 'x'));
console.log(filter(a, 'x', 'name'));
.as-console-wrapper { max-height: 100% !important; top: 0; }
like image 27
Nina Scholz Avatar answered Sep 23 '22 17:09

Nina Scholz