9

I have searched on here for a quality method to compare associative arrays in javascript. The only decent solution I have found is the PHP.JS project which has some comparative array functions. The only problem is that these functions consider the first array as the key to the second. In my situation at least both arrays do not always have the same # of keys nor the same keys. This causes the functions to output results that do not include keys that may not have existed in array1 but existed in array2. The only thing I can think of so far is to run the array_diff_associative() function twice with the arguments flipped and then combine them(which seems problematic since the first argument again is used as the keys to the second).

Any suggestions? Thank you.

3 Answers3

11

This is an old question, but since it comes up first in a google search for comparing arrays, I thought I would throw in an alternative solution that works even when the array has two different objects with the same values.

function arrays_equal(a, b) {
    return JSON.stringify(a) == JSON.stringify(b);
}

Note: This is order dependent, so if order doesn't matter, you can always do a sort ahead of time.

Brainware
  • 531
  • 6
  • 15
8

I think the following should do what you want:

function nrKeys(a) {
    var i = 0;
    for (key in a) {
        i++;
    }
    return i;
}
function compareAssociativeArrays(a, b) {
   if (a == b) {
       return true;
   }   
   if (nrKeys(a) != nrKeys(b)) {
       return false;
   }
   for (key in a) {     
     if (a[key] != b[key]) {
         return false;
     }
   }
   return true;
}
Dean Povey
  • 9,256
  • 1
  • 41
  • 52
  • 1
    just wondering, shouldn't your first comparison in compareAssociativeArrays be if (a === b) ? – Dave Archer Jul 10 '09 at 10:44
  • Your solution has two drawbacks: (1) it would incorrectly return true in the case when a and b have the same sizes, and a has a key that points to an undefined value, while b doesn't have that key. (2) it would incorrectly return false in the case when there exists two values inside a and b, which have the same values, but are in fact objects and are not equal by a '==' operator. While it's easy to fix (1), it would require more effort to fix (2). As an alternative solution, I would use just a **toString()**, or even faster, **join('')** method to compare two strings. – CuongHuyTo Jul 07 '11 at 14:00
  • One reported downside is that [toString() does not work in Netscape 2 and Explorer 3](http://www.quirksmode.org/js/strings.html) – CuongHuyTo Jul 07 '11 at 14:00
  • I've updated this function: https://gist.github.com/skylord123/e595f97516e979c40905657527844c46 May be useful for some despite this question being really really old. – Skylord123 Feb 22 '17 at 19:23
2

I really don't know if there is a nicer way to do it than the brute force approach:

function differences(a, b){
  var dif = {};
  for(key in a){ //In a and not in b
    if(!b[key]){
      dif[key] = a[key];
    }
  }
  for(key in a){ //in a and b but different values
    if(a[key] && b[key] && a[key]!=b[key]){
      //I don't know what you want in this case...
    }
  }
  for(key in b){ //in b and not in a
    if(!a[key]){
      dif[key] = b[key];
    }
  }
  return dif;
}

Also, they are objects, not arrays, and some properties will not be enumerable through for..in (like Array.length, for example), so take it into account for your application.

Victor
  • 9,210
  • 3
  • 26
  • 39