views:

1833

answers:

4

Hi all,

I have two arrays of JavaScript Objects that I'd like to compare to see if they are the same. The objects may not (and most likely will not) be in the same order in each array. Each array shouldn't have any more than 10 objects. I thought jQuery might have an elegant solution to this problem, but I wasn't able to find much online.

I know that a brute nested $.each(array, function(){}) solution could work, but is there any built in function that I'm not aware of?

Thanks.

+1  A: 

I don't think there's a good "jQuery " way to do this, but if you need efficiency, map one of the arrays by a certain key (one of the unique object fields), and then do comparison by looping through the other array and comparing against the map, or associative array, you just built.

If efficiency is not an issue, just compare every object in A to every object in B. As long as |A| and |B| are small, you should be okay.

Stefan Kendall
@Stefan, thanks for the quick response. Can you post example code for your mapping idea? Thanks.
Mega Matt
A: 

It's not native jQuery and not the slickest code by any means, but....

http://www.mail-archive.com/[email protected]/msg16923.html

function arrayMatch( a, b ) {
      var o = {};
      for( var i = a.length; --i >= 0; )
         o[ a[i] ] = true;
      for( var i = b.length; --i >= 0; )
         if( o[ b[i] ] )
            return true;
      return false;
   }
easement
I saw this as well
Mega Matt
This will only test if one of the elements of a is in b.
Stefan Kendall
This also won't work for comparing arrays of objects.
Stefan Kendall
+2  A: 
jQuery.fn.compare = function(t) {
    if (this.length != t.length) { return false; }
    var a = this.sort(),
        b = t.sort();
    for (var i = 0; t[i]; i++) {
     if (a[i] !== b[i]) { 
      return false;
     }
    }
    return true;
};

Updated: I updated the example to work as the OP intended (sorting the arrays), example:

var a = [0,2]
var b = [2,0]

alert($(a).compare(b));

should alert true;

Update 2: I cached the sorted arrays just for the good.

David
Am I wrong in thinking this function will only return true if both arrays have their values in the same order? From your question, this would not seem to be the desired result.
Doug Neiner
@dcneiner: yes, that was what I thought too. You'd have to sort the lists before comparing them for this version to work.
bobince
you are both right, I updated the example. If the arrays gets big, you can cache the sorted arrays before comparing.
David
Isn't sorting on every comparison the worst idea ever?
Stefan Kendall
@Stefan: ok, seemed obvious, but I edited the code again to cache the sorted arrays. thanks
David
+1  A: 

Well, if you want to compare only the contents of arrays, there's a useful jQuery function $.inArray()

var arr = [11, "String #1", 14, "String #2"];
var arr_true = ["String #1", 14, "String #2", 11]; // contents are the same as arr
var arr_false = ["String #1", 14, "String #2", 16]; // contents differ

function test(arr_1, arr_2) {
    var equal = arr_1.length == arr_2.length; // if array sizes mismatches, then we assume, that they are not equal
    if (equal) {
        $.each(arr_1, function (foo, val) {
            if (!equal) return false;
            if ($.inArray(val, arr_2) == -1) {
                equal = false;
            } else {
                equal = true;
            }
        });
    }
    return equal;
}

alert('Array contents are the same? ' + test(arr, arr_true)); //- returns true
alert('Array contents are the same? ' + test(arr, arr_false)); //- returns false
Vilius Pau
Good solution, but I'm not sure this is accounting for the arrays having the same elements, but in a different order.
Mega Matt
You can move if (!equal) return false; down to the bottom of $.each to avoid firing the function again. And you can return equal; to avoid a comparison.
envalid