Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Сравнение объектов (https://javascript.ru/forum/misc/10792-sravnenie-obektov.html)

Cepin 21.07.2010 11:30

Спасибо. Все гениальное просто) Благодарю.

tenshi 25.07.2010 14:47

Object.prototype.valueOf= function(){ return JSON.stringify( this ) }

alert( {a:{b:2}} == {a:{b:2}} )

Ivan Galin 17.06.2011 19:25

Метод конечно простой и удобный, но ...
var o1 = {a:1,b:2}, s1 = JSON.stringify(o1),
    o2 = {b:2,a:1}, s2 = JSON.stringify(o2);
console.log(s1 == s2);            //  false
console.log(s1);                  // {"a":1,"b":2}
console.log(s2);                  // {"b":2,"a":1}

nikita.mmf 20.06.2011 13:41

Object.equal = function( firstObj, secondObject ){
	var keysFirstObj = Object.keys( firstObj );
	var keysSecondObject = Object.keys( secondObject );
	if ( keysFirstObj.length != keysSecondObject.length ) {
		return false;
	}
	return !keysFirstObj.filter(function( key ){
		if ( typeof firstObj[key] == "object" ||  Array.isArray( firstObj[key] ) ) {
			return !Object.equal(firstObj[key], secondObject[key]);
		} else {
			return firstObj[key] !== secondObject[key];
		}
	}).length;
}
alert(Object.equal({a:[1,2,{b:1}], c: {d:[1,2,3]}},{a:[1,2,{b:1}], c: {d:[1,2,3]}}));

andrewinc 11.10.2012 00:24

Немного доработал предыдущий вариант, если кому интересно.

/** сравнить объекты по значению рекурсивно все свойства.
 *@param Object firstObj один из объектов для сравнения
 *@param Object secondObject другой объект для сравнения
 *@return boolean true одинаковы, false - различаются
 *Пр.: Object.equals({a:[1,2,3],b:2}, {b:2,a:[1,2,3]}); //true
 *     Object.equals(null, null); //false
 *     Object.equals(1, 1); //true
 *     Object.equals(1, '1');//true
 *     Object.equals(1, {a:1});//false
 *     Object.equals([1,2], [1,2]);//true
 *     Object.equals(new Date(), new Date())//true
 *     
 *     var d= new Date();
 *     var d2= new Date(d.getTime()+3600000);
 *     Object.equals(d, d2); //false
 *     Object.equals(d, d); //true
 *     Object.equals(d, new Date(d.getTime())); //true
 **/
Object.equals = function( firstObj, secondObject ){
    if ((null==firstObj)||(null==secondObject)) return false; //null сравниваем правильно. Если хоть в одном операнде значит false
    if (('object'!=typeof firstObj) && ('object'!=typeof secondObject))  return firstObj==secondObject;//оба из простых - сравнение простых значений. 
    else if (('object'!=typeof firstObj) || ('object'!=typeof secondObject)) return false;//сравнивается простое значение с объектом - всегда не равны
    //в этой точке только если сравниваем именно объекты (оба)    
    
    //отдельно для дат
    if ((firstObj instanceof Date) && (secondObject instanceof Date)) return firstObj.getTime()==secondObject.getTime(); //исключение для дат. сравним их по микросекундам
    else if ((firstObj instanceof Date) && (secondObject instanceof Date)) return false;//Если дата сравнивается с чем-то ещё -то всегда выдать несоответствие
    
    //далее сравниваем нормальные объекты
    var keysFirstObj = Object.keys( firstObj );
    var keysSecondObject = Object.keys( secondObject );
    if ( keysFirstObj.length != keysSecondObject.length ) {return false;}
    return !keysFirstObj.filter(function( key ){
        if ( typeof firstObj[key] == "object" ||  Array.isArray( firstObj[key] ) ) {
            return !Object.equals(firstObj[key], secondObject[key]);
        } else {
            return firstObj[key] !== secondObject[key];
        }
    }).length;
}

alert(Object.equals({a:[1,2,3],b:2}, {b:2,a:[1,2,3]})); //true
alert(Object.equals(null, null); //false
alert(Object.equals(1, 1); //true
alert(Object.equals(1, '1');//true
alert(Object.equals(1, {a:1});//false
alert(Object.equals([1,2], [1,2]);//true
alert(Object.equals(new Date(), new Date())//true

Maxmaxmахimus 11.10.2012 00:31

tenshi, же написал


Object.prototype.valueOf= function(){ return JSON.stringify( this ) }

alert( {a:{b:2}} == {a:{b:2}} )

Nekromancer 11.10.2012 00:43

https://github.com/NekR/Sync/blob/master/core.js#L248

nerv_ 11.10.2012 01:08

Nekromancer, особо не вглядывался, но при сравнении объектов с "бесконечными" ссылками не зависает из-за рекурсии?

пример "бесконечной" ссылки

var obj = {
    a: some_value,
    b: obj
};

Nekromancer 11.10.2012 01:18

Ну наверно зависнет, да :) Надо поставить ограничение наверно. Я этот метод не использовал, кажется, просто написал.

Aetae 11.10.2012 01:40

Ну, от рекурсии при сериализации избавится просто - составлять по мере исследования массив объектов.
Но для сравнения этого скорее всего не нужно.


Часовой пояс GMT +3, время: 15:23.