Aman Gupta
Aman Gupta

Reputation: 1874

NodeJS: Comparing each element of an array with all other elements with an async process?

I am using Resemble.js to compare images in my web application. I get an array of images(urls). I want to compare the images with every other image in the array and calculate the unique score of that image. Eg. [url1, url2, url3, url4] So the minimum combination will be

1 => 2
1 => 3
1 => 4
2 => 3
2 => 4
3 => 4

But i would also need to store the opposite combination values(although they would be same) Eg. 1 => 2 will be same as 2 => 1

Question How do i run the loop something like

 for (var i = 1; i<=arr.length; i++) {
    for (var j = i+1; j <=arr.length; j++) {
        console.log(i + " => " + j);
       //async operation to compare two images
    }
}

using the async module for Nodejs. Also not comparing two images again for their opposite combination result. instead use the already calculated score.

EDIT

MODIFIED my existing code which works very fine and gives correct results and is pretty fast too. Is there any way i can optimize it further?

var arr = [ 
        {url: 'url1'}, {url:'url2'}, {url:'url3'}
    ];

    function range(length) {
        var l = [];
        var counter = 0;
        for (var i = 0; i < length; i++) {
            for (var j = 0; j < length; j++) {
                if(i != j){
                    l[counter] = {
                        i: i,
                        j: j
                    };
                    counter++;  
                }

            }
        }
        return l;
    }

    var ijs = range(arr.length);
    var tempUS = 0; 
    async.each(ijs, function (ij, cb) {
            if(ij.i != ij.j && ij.i > ij.j) {
                resemble(arr[ij.i].url).compareTo(arr[ij.j].url).onComplete(function(data) {
                   console.log(data.misMatchPercentage);
                   ij.score = data.misMatchPercentage;
                   cb();
                }); 
            }
            else {
                cb();
            }

        },
        function(err){
            if(err) {
                console.log(err);
            }
            else {
                for(var e = 0; e <arr.length; e++) {
                    var z = 0;
                    for(var f = 0; f < ijs.length; f++) {
                        if(ijs[f].i == e) {
                            if(ijs[f].score) {
                                z = z+ parseFloat(ijs[f].score);    
                            }

                        }
                        else if(ijs[f].j == e) {
                            if(ijs[f].score) {
                                z = z+ parseFloat(ijs[f].score);    
                            }

                        }
                    }
                    console.log(e, " ======== ", z);
                    var avg = z/arr.length;
                    arr[e].uniqueScore = avg;
                }
                console.log(arr);

            }
        });

Upvotes: 0

Views: 932

Answers (1)

Callum Linington
Callum Linington

Reputation: 14417

If you bring in the async module and do:

function range(length) {
    var l = [];
    var counter = 0;
    for (var i = 0; i < length; i++) {
        for (var j = i + 1; j < length; j++) {
            l[counter] = {
                i: i,
                j: j
            };
            counter++;
        }
        counter++;
    }
    return l;
}

var ijs = range(arr.length);

async.each(ijs, function (ij, cb) {
    resemble(arr[ij.i])compareTo(arr[ij.j]).onComplete(function(data){
       // data; // do something with data
       cb(); // call the callback so we know we can move on
       /*
       {
          misMatchPercentage : 100, // %
          isSameDimensions: true, // or false
          getImageDataUrl: function(){}
       }
       */
    });
});

Edit

Updated my range function to exclude duplicates.

Upvotes: 1

Related Questions