En una entrevista reciente, me pidieron que creara un método flat
que aplana un objeto. Intenté implementarlo de la siguiente manera, pero no funciona:
Object.defineProperty(Object.prototype, 'flat', { enumerable: false, writable: true, configurable: false, value: function() { function flatten(obj) { for(let key in obj) { if(obj.hasOwnProperty(key)) { if(typeof obj[key] === 'object') { obj[key] = flatten(obj[key]) } else { obj[key] = obj[key]; } } } return obj; } flatten(this); } }); var obj = { a: 1, b: 2, c: { d: { e: 5 }, f: 6 } } obj.flat(); console.log(obj); // should return { a: 1, b: 2, e: 5, f: 6 }
¿Qué hay de malo en mi código?
PD: otra publicación en SO para aplanar Object no lo haga en el lugar, que es el requisito en este caso.
Estás creando la misma estructura de objeto recursivo aquí:
obj[key] = flatten(obj[key])
En su lugar, debe colocar las propiedades anidadas en el objeto original. También debe eliminar las propiedades intermedias del objeto original, de modo que solo le queden las propiedades al final.
También recomendaría encarecidamente no mutar prototipos integrados, especialmente Object.prototype
: puede generar problemas de compatibilidad y un comportamiento confuso, especialmente cuando las bibliotecas están involucradas. Las cosas se romperán eventualmente como resultado. Utilice una función simple en su lugar.
const flatten = (base, obj = base) => { for (const [key, value] of Object.entries(obj)) { if (typeof value === 'object' && value !== null) { delete obj[key]; flatten(base, value); } else { base[key] = value; } } }; var obj = { a: 1, b: 2, c: { d: { e: 5 }, f: 6 } } flatten(obj); console.log(obj);
Con la ayuda de la otra respuesta, obtuve el código exacto que quería:
Object.defineProperty(Object.prototype, 'flat', { enumerable: false, writable: true, configurable: false, value: function() { function flatten(base, obj) { for(let key in obj) { if(obj.hasOwnProperty(key)) { if(typeof obj[key] === 'object' && obj[key] !== null) { flatten(base, obj[key]); delete obj[key]; } else { base[key] = obj[key]; } } } } flatten(this, this); } }); var obj = { a: 1, b: 2, c: { d: { e: 5 }, f: 6 } } obj.flat(); console.log(obj); // returns { a: 1, b: 2, e: 5, f: 6 }