JavaScript, сравнивающий массивы объектов - PullRequest
1 голос
/ 10 сентября 2011

Я получаю «Превышен максимальный размер стека вызовов». пытаясь перебрать содержимое массива, и я не могу на всю жизнь понять, почему Редактировать: Кстати, я хочу добавить, что это для Safari

вот функция:

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)
}

Я получаю перегрузку в операторе возврата функции u ()

1 Ответ

2 голосов
/ 10 сентября 2011

Ваша функция может быть намного короче. Желательно использовать значимые имена функций. Некоторые функции являются избыточными. Нет необходимости в рекурсии. Я позволил себе переписать вашу функцию, просто для демонстрации. Вы можете увидеть это в действии здесь .

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);
}

На самом деле, если вы используете JSON (нативно в новых браузерах или из библиотеки), вы можете сделать все это, просто используя:

function compare(a,b){
  return JSON.stringify(a) === JSON.stringify(b);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...