Skip to content Skip to sidebar Skip to footer

Comparing Javascript Arrays

I would like a function that compares to arrays of javascript strings, and saving the values that didnt match in to a new array. At the moment im using a nested jquery foreach. But

Solution 1:

How about this:

arr1.forEach( function ( elem ) {
    if ( arr2.indexOf( elem ) > -1 ) {
        // match...
    }
});

where arr1 and arr2 are your two arrays...

(Btw, ES5 shim for IE8, of course...)

Solution 2:

Here's a way using a JSON object and no jQuery, although the $.inArray() should work fine:

var imagesInUploadsFolder = [
    '/path/to/img1.png',
    '/path/to/img2.png',
    '/path/to/img3.png'
];
var imagesInDatabaseTable = [
    '/path/to/img1.jpg',
    '/path/to/img2.png',
    '/path/to/img4.png'
];

var database_json = JSON.stringify(imagesInDatabaseTable);

for (var i = 0; i < imagesInUploadsFolder.length; i++) {
    console.log(imagesInUploadsFolder[i] + ' in ' + database_json);
    if (database_json.indexOf(imagesInUploadsFolder[i]) > -1) {
        console.log('In database: ' + imagesInUploadsFolder[i]);
    } else {
        console.log('Not in database: ' + imagesInUploadsFolder[i]);
    }
}

http://jsfiddle.net/7nJPW/1/

EDIT

Actually, the JSON method isn't needed (?):

for (var i = 0; i < imagesInUploadsFolder.length; i++) {
    console.log(imagesInUploadsFolder[i] + ' in ' + imagesInDatabaseTable);
    if (imagesInDatabaseTable.indexOf(imagesInUploadsFolder[i]) > -1) {
        console.log('In database: ' + imagesInUploadsFolder[i]);
    } else {
        console.log('Not in database: ' + imagesInUploadsFolder[i]);
    }
}

http://jsfiddle.net/7nJPW/2/

Solution 3:

Why not use foreach of pure javascript?

for (var i = 0; i < innervalue.length; i++) {
    for (var j = 0; j < outervalue.length; j++){
        if (innervalue[i] === outervalue[j])
           // match
    }
}

Solution 4:

It is the most easier way i can think of right now :)

 $.each(imagesInUploadsFolder, function(i, outervalue){
       if($.inArray(imagesInDatabaseTable,outervalue)>-1){
               //my operation
       }
    }

FYI: Actually inArray returns index of innermatch else -1. Just incase you need it.

Solution 5:

Whether you use jQuery or for loops, straight-out comparison will be O(n), since you'll need to compare each element of one array with every element of another array.

If the objects are comparable, you can sort the items using a suitable comparison function, then loop over the two arrays simultaneously, examining if one element is less than the other. If you're familiar with merge-sort, this is very similar to the merge step. Assuming the comparison function is O(1), sorting is O(nlog(n)), and the merge-like comparison loop is O(n), the total time complexity is O(nlog(n)), where "n" is the length of the larger array.

    imagesInUploadsFolder.sort(imgCmp);
    imagesInDatabaseTable.sort(imgCmp);
    // diff will hold the difference of the arraysvar diff = [];
    var i=0, j=0, cmp;
    while (i < imagesInUploadsFolder.length && j < imagesInDatabaseTable.length) {
        cmp = cmp(imagesInUploadsFolder[i], imagesInDatabaseTable[j]);
        if (cmp < 0) {
            // up[i] < db[j]
            ++i;
            diff.append(imagesInUploadsFolder[i]);
        } elseif (cmp > 0) {
            // up[i] > db[j]
            ++j;
            diff.append(imagesInDatabaseTable[j]);
        } else {
            // up[i] == db[j]
            ++i; ++j;
        }
    }
    // one of the arrays may still have items; if so, loop over it and add the itemsif (i < imagesInUploadsFolder.length) {
        for (; i < imagesInUploadsFolder.length; ++i) {
            diff.append(imagesInUploadsFolder[i]);
        }
    } elseif (j < imagesInDatabaseTable.length)) {
        for (; i < imagesInDatabaseTable.length; ++i) {
            diff.append(imagesInDatabaseTable[i]);
        }
    }
    // diff now holds items that are in only one of the two arrays.

If you can define a suitable object ID function, you can create an ancillary data structure that holds a set of elements. If accessing object properties is O(f(n)) (for hashes, f ≈ 1; for balanced trees, f = log(n)), then this approach is O(n*f(n)), so it should have no worse complexity than the sort-and-compare approach. Untested and inefficient implementation:

functionSet(from) {
    this.elements = {};
    this.size = 0;
    if (from) {
        for (var i=0; i < from.length) {
            this.add(from[i]);
        }
    }
}
Set.prototype.each = function(f) {
    var eltId;
    foreach (eltId inthis.elements) {
        f(this.elements[eltId], eltId);
    }
};
Set.prototype.clone = function() {
    var clone = newSet();
    this.each(function(obj, id) {
        clone.add(obj);
    });
    return clone;
};
Set.prototype.contains = function(obj) {
    return obj.uniqueId() inthis.elements;
};
Set.prototype.add = function(obj) {
    var objId = obj.uniqueId();
    if (! (objId inthis.elements)) {
        ++this.size;
        this.elements[objId] = obj;
    }
    returnthis;
};
Set.prototype.remove = function(obj) {
    var objId = obj.uniqueId();
    if (objId inthis.elements) {
        --this.size;
        deletethis.elements[objId];
    }
    returnthis;
};
Set.prototype.union = function(other) {
    other.each(function(elt, id) { this.add(elt); });
    returnthis;
};
Set.prototype.sub = function(other) {
    other.each(function (elt, id) {
        this.remove(elt);
    });
    returnthis;
};
Set.prototype.diff = function(other) {
    var mine = this.clone();
    mine.sub(other);
    var others = other.clone();
    others.sub(this);
    mine.union(others);
    return mine;
};
Set.prototype.toArray = function(obj) {
    var arr = [];
    this.each(function(elt, id) {
        arr.append(elt);
    });
    return arr;
};

var uploadsSet = newSet(imagesInUploadsFolder),
    dbSet = newSet(imagesInDatabaseTable),
    imagesInJustOne = uploadsSet.diff(dbSet);

If you want both the union and difference of the arrays, you can define a suitable method on Set to more efficiently calculate them instead of using Set.diff and Set.union separately.

Post a Comment for "Comparing Javascript Arrays"