javascriptjsonsearch

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!


Solution

  • 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 '));