Javascript: improve four nested loops?

I have a complex array of objects with nested arrays. The following works are designed to extract certain objects, but this is one of the ugliest things I wrote.

Do you have dark javascript magic to make it elegant?

function getEighthInsertionBlocks() {
    var struct = Lifestyle.Pagination.structure;
    var blocks = [];
    for (var i = 0; i<struct.length; i++) {
        var page = struct[i];
        var layers = page.children;
        for (var j=0; j<layers.length; j++) {
            var layer = layers[j];
            if (layer.className === 'EighthPageLayer' ) {
                var rows = layer.children;
                for (var k=0; k<rows.length; k++) {
                    var row = rows[k];
                    eBlocks = row.children;
                    for (var l=0; l<eBlocks.length; l++) {
                        blocks.push(eBlocks[l]);
                    }
                }
            }
        }
    }

    return blocks;
}

Not that I'm a big fan of code golf, but ... it's awful.

+4
source share
3 answers

You could write a generic iterator that would reduce the code to consecutive blocks:

var iterator = function(collection, callback){
    var length = collection.length;
    var results = [];
    var result;
    for (var i = 0; i < collection.length; i++){
        result = callback(colleciton[i], i);
        if (result){
            results = results.concat(result);
        }
    }
    return results;
};

function getEighthInsertionBlocks() {
    var struct = Lifestyle.Pagination.structure;
    var layers = iterator(struct, function(page){ return page.children; });
    var rows = iterator(layers, function(layer){
        return layer.className === 'EighthPageLayer' ? layer.children : null;
    });
    return iterator(rows, function(eBlocks, index){ return eblocks[index]; });
}
+3
source

I usually prefer to use forEachfor readability, but this is subjective.

function isEighthPageLayer(layer){
    return layer.className === "EighthPageLayer"
}

function getEighthInsertionBlocks(struct) {
    var blocks = [];
    struct.forEach(function(page){
        page.layers
            .filter(isEighthPageLayer)
            .forEach( function(layer) {
                layer.children.forEach(function(row){
                    row.children.forEach(function(eBlocks){
                        blocks.push(eBlocks);
                    });
                });
            });
        });
    });
    return blocks;
}
0
source

. , , , . , , , . . , , , , :

function iterateLevel(data, options, level, output) {
    console.log("level:" + level);
    console.log(data);
    var fn = options[level] && options[level].fn;
    for (var i = 0; i < data.length; i++) {
        if (!fn || (fn(data[i]) === true)) {
            if (level === options.endLevel) {
                output.push(data[i]);
            } else {
                iterateLevel(data[i].children, options, level + 1, output);
            }
        }
    }
}

var iterateOptions = {
    "1": {
        fn: function(arg) {return arg.className === 'EighthPageLayer'}
    },
    "endLevel": 3
}
var blocks = [];
iterateLevel(Lifestyle.Pagination.structure, iterateOptions, 0, blocks);

, options , , .

: http://jsfiddle.net/jfriend00/aQs6h/

0

All Articles