Styler2go Styler2go - 2 months ago 5
Javascript Question

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 < filter.length; c++) {
var splittedFilter = filter[c].split('.');
for (var s = 0; s < splittedFilter.length; s++) {
var obj = haystack[splittedFilter[s]];
if (obj){
if (Array.isArray(obj) && obj.length > 0){
for (var i = 0; i < 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"
}
]
}
];


and the execution of the search function:

hay.forEach(function(element) {
if (searchFor('Duke', element, filter)) {
document.getElementById('result').innerHTML = document.getElementById('result').innerHTML + '<br />' + 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 an live example here: https://jsfiddle.net/6kr3zneh/2/

Answer

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; }

Comments