Estoy tratando de comparar dos objetos del mismo tipo. Lo que quiero lograr al final es un nuevo objeto con solo las propiedades que son diferentes.
La solución implementada hasta ahora, con ayuda previa en otra publicación, de hecho me devolverá un objeto con las propiedades que han cambiado, pero, si las propiedades en los objetos internos no están en el mismo orden, lo que sucede desde el el orden de las propiedades de los objetos no es estándar en ECMAScript, también los obtendré en el objeto final, que no es lo que quiero.
En el siguiente ejemplo:
z
vuelve
{ "properties": { "shared": false, "query": "project!=\"JP\"" } }
mientras que me gustaría que z
fuera:
{ "properties": { "query": "project!=\"JP\"" } }
ya que la única propiedad diferente entre los dos objetos es query
type X = { owner: { accountId: string, displayName: string }, filter: { id: string, name: string, }, properties: { id: string, query: string shared: boolean syncDate?: number } } const a: X = { filter: { id: "10021", name: "fil" }, owner: { accountId: "61498eeaa995ad0073bb8444", displayName: "Jorge Guerreiro" }, properties: { id: "10021", query: 'project!="JP"', shared: false, syncDate: undefined } } const b: X = { filter: { id: "10021", name: "fil" }, owner: { accountId: "61498eeaa995ad0073bb8444", displayName: "Jorge Guerreiro" }, properties: { id: "10021", shared: false, query: 'project="JP"', syncDate: undefined } } const deepCompare = <T>(oldFilter: T, newFilter:T): Partial<T> => { return Object.values(oldFilter).reduce((bef, aft, i) => { const valueB = Object.values(newFilter)[i]; const keyB = Object.keys(newFilter)[i]; if (valueB instanceof Object && keyB) { const delta = deepCompare(valueB, aft); return Object.keys(delta).length > 0 ? { [keyB]: deepCompare(valueB, aft), ...bef } : bef; } return valueB !== aft && keyB ? { [keyB]: valueB, ...bef } : { ...bef }; }, {}); } const z = deepCompare<X>(a, b)
Estoy un poco atascado en cómo hacer que la función recursiva a continuación haga lo que quiero. Cualquier ayuda sería genial.
Gracias
prueba esto
// scope to return the end result const deepCompare = <T>(oldFilter: T, newFilter:T): Partial<T> => { // resursive function where the target argument // will be the filtered result of the current entry const traverse = (obj: any, filter: any, target: any = {}) => { // looping entries by key is the most performant way to // iterate through obj properties for (let k in obj) if (obj[k] instanceof Object && filter[k]) { // ad level, go deeper target[k] = {} let targetResult = traverse(obj[k], filter[k], target[k]) // delete empty entries if so desired if (!Object.keys(targetResult).length) delete target[k] } else if (obj[k] !== filter[k]) target[k] = obj[k] // store value return target } return traverse(oldFilter, newFilter) } deepCompare(a,b)
para escribir, necesita hacer que sus objetos sean indexables para que el mecanografiado no se queje, generalmente hago una clave genérica keyof typeof T[k]
o infiero los agrumentos anidados