Newfoundland Newfoundland - 6 months ago 34
Javascript Question

jQuery iterate through array of objects recursively and return a value

I have the following json which represents pages on a site which have sub pages via an items array, which currently comprises 2 top level items - about and services:

var data = '[{"id":107,"name":"About Us","route":"page","slug":"about","parent":0,"module":1,"items":[{"id":118,"name":"About Sub Page","route":"page","slug":"about-sub-page","parent":107,"items":[]}]},{"id":129,"name":"Services","route":"page","slug":"services","parent":0,"module":1,"items":[{"id":174,"name":"Services sub page","route":"page","slug":"services-sub-page","parent":129,"items":[]}]}]';


I am trying to write a function which iterates recursively over the array of objects (data = JSON.parse(data)) and identify the index of the top level items. For instance, in my function if I use the 'about' slug, it will return 0, as will 'about-sub-page'. Similarly, 'services-sub-page' would return 1.

I have this at the moment:

data = JSON.parse(data);

function check(slug,data) {
var result;
$.each(data, function(index){
if (this.slug === slug) {
result = index;
return false;
}
else {
check(slug,this.items);
}
});
return result;
}


This works fine if I pass a top level slug eg

var index = check('about',data);
console.log(index); // returns 0

var index = check('services',data);
console.log(index); // returns 1


However, if I try with a sub page I get undefined

var index = check('services-sub-page',data);
console.log(index); // returns undefined


I believe I need to return false to break out of the each loop, but not sure why it's not working when I try and use the function recursively.

Answer

You could use Array#some(), because this stops iterating if a condition is met.

var data = '[{"id":107,"name":"About Us","route":"page","slug":"about","parent":0,"module":1,"items":[{"id":118,"name":"About Sub Page","route":"page","slug":"about-sub-page","parent":107,"items":[]}]},{"id":129,"name":"Services","route":"page","slug":"services","parent":0,"module":1,"items":[{"id":174,"name":"Services sub page","route":"page","slug":"services-sub-page","parent":129,"items":[]}]}]';

function check(slug, data) {
    function iter(a, i) {
        if (a.slug === slug || Array.isArray(a.items) && a.items.some(iter)) {
            index = i;
            return true;
        }
    }

    var index,
        array = JSON.parse(data);

    array.some(iter)
    return index;
}

document.write(check('about', data) + '<br>');
document.write(check('services', data) + '<br>');
document.write(check('services-sub-page', data) + '<br>');

Comments