开发者

javascript comparing arrays of objects

I'm getting a "Maximum call stack size exceeded." while trying to iterate the contents of an array and I can't for the life of me figure out why Edit: By the way I want to add that this is for Safari

here's the function:

function compareObj(a,b) {
var u = function(c,d) {//Check types
    var type = Object.prototype.toString.call(a)

    if (type !== Object.prototype.toString.call(b)) return false

    return type.slice(8,-1) == 'Array' ? v(a,b) : type.slice(8,-1) == 'Object' ?  w(a,b) :
           type.slice(8,-1) == 'String' ? x(a,b) : type.slice(开发者_开发知识库8,-1) == 'Number' ? y(a,b) :
           type.slice(8,-1) == 'Boolean' ? z(a,b) : false ;
}

var v = function(c,d) {//Array
    if (c.length !== d.length) return false
    /*for (var i = 0; i < c.length; i++) {
        if (!u(c[i],d[i])) {
            return false
        }
    }*/
    while (c.length) {
        if (!u(c[0],d[0])) {
            return false
        } else {
            c.shift();
            d.shift();
        }
    }
    return true
}

var w = function(c,d) {//Object
    for (i in c) {

    }
    return true
}

var x = function(c,d) {//String
    return c === d
}

var y = function(c,d) {//Number
    return c === d
}

var z = function(c,d) {//Boolean
    return c === d
}

return u(a,b)
}

I get the overload in the return statement of the u() function


Your function can be a lot shorter. It's advisable to use meaningfull function names. Some functions are redundant. There is no need for recursion. I took the liberty to rewrite your function, just for demonstration. You can see it in action here.

function compareObj(a,b) {
var doCompare = function(c,d) {
    //Check types (IE compatible)
    var objRE = /Array|Object|String|Number|Boolean/,
        aType = a.constructor.name || String(a.constructor).match(objRE)[0],
        bType = b.constructor.name || String(b.constructor).match(objRE)[0];

    //Types different? No dice.
    if (aType !== bType) {return false;}

    switch(aType){
        case 'Array'  : return arrayCompare(a,b); break;
        case 'Object' : return objectCompare(a,b); break;
        case 'String' : return valueCompare(a,b); break;     
        case 'Number' : return valueCompare(a,b); break;
        case 'Boolean': return valueCompare(a,b); break;
       default: return false
    }
   }

  var arrayCompare = function(c,d) { //Array
      if (c.length !== d.length) {return false;}
      var i = c.length;
      while (--i) {
        if ( !valueCompare(c[i],d[i]) ) {
            return false;
        }
      }
    return true;
  }

   var objectCompare = function(c,d) { //Object
     //you'll have to consider the number of elements too  
     var lenb = 0, lena = 0;
     for (var label in d){
         if (d.hasOwnProperty(label)) { lenb+=1; } 
     }
     for (var label in c) {
       if (c.hasOwnProperty(label)){
        lena += 1;
         if ( !valueCompare(c[label],d[label]) ) {
            return false;
         }
       }      
     }
     return lena === lenb; 
  }

  var valueCompare = function(c,d) {//String
    return JSON.stringify(c) === JSON.stringify(d);
  }

  return doCompare(a,b);
}

Actually, if you use JSON (native in newer browsers, or from library), you can do all this just using:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜