Search through JavaScript object using a whitelist/filterlist I am trying to build a small search function where I can search through some JavaScript objects even if there are arrays in it. I got it working but I would like to ask if someone can find a better approach than the one I made. Also, I assume I have some cases I did not think of.

My current search function looks as follows:

function searchFor(needle, haystack, filter, inside){
    if (inside == undefined) inside = 1;
    if (filter){
        for (var c = 0; c &lt; filter.length; c++) {
            var splittedFilter = filter[c].split('.');
            for (var s = 0; s &lt; splittedFilter.length; s++) {
                var obj = haystack[splittedFilter[s]];
                if (obj){
                    if (Array.isArray(obj) &amp;&amp; obj.length &gt; 0){
                        for (var i = 0; i &lt; obj.length; i++) {
                            var result = searchFor(needle, obj[i], [splittedFilter[inside]], inside+1);
                            if (result) return true;
                        }
                    } else if( typeof obj == "object"){
                        var result = searchFor(needle, obj, [splittedFilter[inside]], inside+1);
                        if (result) return true;
                    } else {
                        if (obj.toLowerCase().indexOf(needle.toLowerCase()) != -1){
                            return true;
                        }
                    }
                }
            }
        }
    }
    return false
}


The filterlist:

var filter = ['company', 'friends.name'];


The haystack:

var hay =  [
  {
    "id": "57db96f4acfaec3218383063",
    "name": {
      "first": "Nora",
      "last": "Cooke"
    },
    "company": "MITROC",
    "email": "nora.cooke@mitroc.com",
    "friends": [
      {
        "id": 0,
        "name": "West Duke"
      },
      {
        "id": 1,
        "name": "Williams Kelley"
      },
      {
        "id": 2,
        "name": "Amelia Kirk"
      }
    ]
  },
  {
    "id": "57db96f4d5cae409054d3a5b",
    "name": {
      "first": "Dickson",
      "last": "Moses"
    },
    "company": "VISUALIX",
    "email": "dickson.moses@visualix.org",
    "friends": [
      {
        "id": 0,
        "name": "Patty Carr"
      },
      {
        "id": 1,
        "name": "Bowers Wilkerson"
      },
      {
        "id": 2,
        "name": "Fox Kidd"
      }
    ]
  }
];


The execution of the search function:

hay.forEach(function(element) {
    if (searchFor('Duke', element, filter)) {
        document.getElementById('result').innerHTML = document.getElementById('result').innerHTML + '&lt;br /&gt;' + JSON.stringify(element);
    }
}, this);



needle is the string to search for
haystack is one object
filter is an array of filters, like: var filter = ['company'];
inside is to determine how far in the recursive loop the function is


I made a live example here.
You could use a simplified version for lookup all needed values and the check against the needle.



function search(needle, haystack, filter) {
    return filter.some(function (f) {
        function iter(o, i) {
            var item;

            if (!(ff[i] in o)) {
                return false;
            }

            item = o[ff[i]];
            i++;

            if (i === ff.length) {
                return item.indexOf(needle) !== -1;
            }

            if (Array.isArray(item)) {
                return item.some(function (a) {
                    return iter(a, i);
                });
            }
            return iter(item, i);
        }

        var ff = f.split('.');

        return iter(haystack, 0);
    });
}

var filter = ['company', 'friends.name'],
    hay = [{ "id": "57db96f4acfaec3218383063", "name": { "first": "Nora", "last": "Cooke" }, "company": "MITROC", "email": "nora.cooke@mitroc.com", "friends": [{ "id": 0, "name": "West Duke" }, { "id": 1, "name": "Williams Kelley" }, { "id": 2, "name": "Amelia Kirk" }] }, { "id": "57db96f4d5cae409054d3a5b", "name": { "first": "Dickson", "last": "Moses" }, "company": "VISUALIX", "email": "dickson.moses@visualix.org", "friends": [{ "id": 0, "name": "Patty Carr" }, { "id": 1, "name": "Bowers Wilkerson" }, { "id": 2, "name": "Fox Kidd" }] }, { "id": "57db96f42215bea719d83036", "name": { "first": "Kerr", "last": "Gray" }, "company": "TUBESYS", "email": "kerr.gray@tubesys.io", "friends": [{ "id": 0, "name": "Rose Pierce" }, { "id": 1, "name": "Matthews Moore" }, { "id": 2, "name": "Brenda Ayala" }] }, { "id": "57db96f435d0f064afc90768", "name": { "first": "Elsie", "last": "Dejesus" }, "company": "KLUGGER", "email": "elsie.dejesus@klugger.us", "friends": [{ "id": 0, "name": "Gina Cruz" }, { "id": 1, "name": "Nieves Carrillo" }, { "id": 2, "name": "Chandler Sanford" }] }, { "id": "57db96f4597631fffff36b6b", "name": { "first": "Chan", "last": "Mcdaniel" }, "company": "AQUACINE", "email": "chan.mcdaniel@aquacine.name", "friends": [{ "id": 0, "name": "Hodge Sweeney" }, { "id": 1, "name": "Sweet Burnett" }, { "id": 2, "name": "Lynn Hunter" }] }];

console.log(hay.map(function (a) {
    return search('Sweet', a, filter);
}));

console.log(hay.map(function (a) {
    return search('Rose', a, filter);
}));
.as-console-wrapper { max-height: 100% !important; top: 0; }