site recorrer objetos objeto lista google for ejemplos convertir array javascript node.js mocha chai

recorrer - objeto window javascript ejemplos



¿Cómo puedo verificar que dos objetos tengan el mismo conjunto de nombres de propiedades? (6)

2 Aquí una versión variada corta de ES6 :

function objectsHaveSameKeys(...objects) { const allKeys = objects.reduce((keys, object) => keys.concat(Object.keys(object)), []); const union = new Set(allKeys); return objects.every(object => union.size === Object.keys(object).length); }

Una pequeña prueba de rendimiento (MacBook Pro - Intel Core i7 a 2,8 GHz, Nodo 5.5.0):

var x = {}; var y = {}; for (var i = 0; i < 5000000; ++i) { x[i] = i; y[i] = i; }

Resultados:

objectsHaveSameKeys(x, y) // took 4996 milliseconds compareKeys(x, y) // took 14880 milliseconds hasSameProps(x,y) // after 10 minutes I stopped execution

Estoy usando node, mocha y chai para mi aplicación. Quiero probar que mi propiedad de datos de resultados devueltos es el mismo "tipo de objeto" que uno de mis objetos modelo. (Muy similar a la instancia de chai). Solo quiero confirmar que los dos objetos tienen los mismos conjuntos de nombres de propiedades. No estoy específicamente interesado en los valores reales de las propiedades.

Digamos que tengo la persona modelo como abajo. Quiero verificar que mi results.data tenga todas las mismas propiedades que el modelo esperado. Así que en este caso, Persona que tiene un nombre y un apellido.

Por lo tanto, si existen results.data.lastName y results.data.firstName , entonces debe devolver verdadero. Si alguno de los dos no existe, debería devolver falso. Un bono sería si results.data tiene propiedades adicionales como results.data.surname, luego devolverá false porque el apellido no existe en Person.

el modelo

function Person(data) { var self = this; self.firstName = "unknown"; self.lastName = "unknown"; if (typeof data != "undefined") { self.firstName = data.firstName; self.lastName = data.lastName; } }


Aquí está mi intento de validar las propiedades JSON. Utilicé el enfoque de @ casey-foster, pero añadí recursión para una validación más profunda. El tercer parámetro en la función es opcional y solo se usa para pruebas.

//compare json2 to json1 function isValidJson(json1, json2, showInConsole) { if (!showInConsole) showInConsole = false; var aKeys = Object.keys(json1).sort(); var bKeys = Object.keys(json2).sort(); for (var i = 0; i < aKeys.length; i++) { if (showInConsole) console.log("---------" + JSON.stringify(aKeys[i]) + " " + JSON.stringify(bKeys[i])) if (JSON.stringify(aKeys[i]) === JSON.stringify(bKeys[i])) { if (typeof json1[aKeys[i]] === ''object''){ // contains another obj if (showInConsole) console.log("Entering " + JSON.stringify(aKeys[i])) if (!isValidJson(json1[aKeys[i]], json2[bKeys[i]], showInConsole)) return false; // if recursive validation fails if (showInConsole) console.log("Leaving " + JSON.stringify(aKeys[i])) } } else { console.warn("validation failed at " + aKeys[i]); return false; // if attribute names dont mactch } } return true; }


Puede serializar datos simples para verificar la igualdad:

data1 = {firstName: ''John'', lastName: ''Smith''}; data2 = {firstName: ''Jane'', lastName: ''Smith''}; JSON.stringify(data1) === JSON.stringify(data2)

Esto te dará algo como

''{firstName:"John",lastName:"Smith"}'' === ''{firstName:"Jane",lastName:"Smith"}''

Como una función...

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

EDITAR

Si estás usando chai como dices, visita http://chaijs.com/api/bdd/#equal-section

Editar 2

Si solo quieres comprobar las teclas ...

function compareKeys(a, b) { var aKeys = Object.keys(a).sort(); var bKeys = Object.keys(b).sort(); return JSON.stringify(aKeys) === JSON.stringify(bKeys); }

Deberías hacerlo.


Si desea comprobar si ambos objetos tienen el mismo nombre de propiedades, puede hacer esto:

function hasSameProps( obj1, obj2 ) { return Object.keys( obj1 ).every( function( prop ) { return obj2.hasOwnProperty( prop ); }); } var obj1 = { prop1: ''hello'', prop2: ''world'', prop3: [1,2,3,4,5] }, obj2 = { prop1: ''hello'', prop2: ''world'', prop3: [1,2,3,4,5] }; console.log(hasSameProps(obj1, obj2));

De esta manera, está seguro de verificar solo las propiedades iterables y accesibles de ambos objetos.

EDITAR - 2013.04.26:

La función anterior se puede reescribir de la siguiente manera:

function hasSameProps( obj1, obj2 ) { var obj1Props = Object.keys( obj1 ), obj2Props = Object.keys( obj2 ); if ( obj1Props.length == obj2Props.length ) { return obj1Props.every( function( prop ) { return obj2Props.indexOf( prop ) >= 0; }); } return false; }

De esta manera, verificamos que ambos objetos tengan el mismo número de propiedades (de lo contrario, los objetos no tienen las mismas propiedades y debemos devolver un falso lógico) y luego, si el número coincide, vamos a verificar si tienen el mismo propiedades

Prima

Una posible mejora podría ser introducir también una verificación de tipo para imponer la coincidencia en cada propiedad.


Si desea una validación profunda como @speculees, aquí hay una respuesta usando deep-keys (revelación: soy una especie de mantenedor de este pequeño paquete)

// obj1 should have all of obj2''s properties var deepKeys = require(''deep-keys''); var _ = require(''underscore''); assert(0 === _.difference(deepKeys(obj2), deepKeys(obj1)).length); // obj1 should have exactly obj2''s properties var deepKeys = require(''deep-keys''); var _ = require(''lodash''); assert(0 === _.xor(deepKeys(obj2), deepKeys(obj1)).length);

o con chai :

var expect = require(''chai'').expect; var deepKeys = require(''deep-keys''); // obj1 should have all of obj2''s properties expect(deepKeys(obj1)).to.include.members(deepKeys(obj2)); // obj1 should have exactly obj2''s properties expect(deepKeys(obj1)).to.have.members(deepKeys(obj2));


Si está usando guiones bajos, simplemente puede usar la función _.isEqual y compara todas las claves y valores en todos y cada uno de los niveles de jerarquía, como se muestra a continuación.

var object = {"status":"inserted","id":"5799acb792b0525e05ba074c","data":{"workout":[{"set":[{"setNo":1,"exercises":[{"name":"hjkh","type":"Reps","category":"Cardio","set":{"reps":5}}],"isLastSet":false,"index":0,"isStart":true,"startDuration":1469689001989,"isEnd":true,"endDuration":1469689003323,"speed":"00:00:01"}],"setType":"Set","isSuper":false,"index":0}],"time":"2016-07-28T06:56:52.800Z"}}; var object1 = {"status":"inserted","id":"5799acb792b0525e05ba074c","data":{"workout":[{"set":[{"setNo":1,"exercises":[{"name":"hjkh","type":"Reps","category":"Cardio","set":{"reps":5}}],"isLastSet":false,"index":0,"isStart":true,"startDuration":1469689001989,"isEnd":true,"endDuration":1469689003323,"speed":"00:00:01"}],"setType":"Set","isSuper":false,"index":0}],"time":"2016-07-28T06:56:52.800Z"}}; console.log(_.isEqual(object, object1));//return true

Si todas las claves y los valores de esas claves son iguales en ambos objetos, devolverá verdadero; de lo contrario, devolverá falso.