Estoy tratando de aplanar un objeto de datos que contiene contenido mixto (JavaScript dentro de una aplicación React). Solo necesito las claves de cada padre e hijo en el objeto; No necesariamente necesito los valores (aunque tenerlos presentes no sería un factor decisivo).
He buscado durante más de una semana para encontrar una solución que se ajuste a mi caso de uso, pero todo lo que he probado se ha quedado corto, incluidos JavaScript estándar, Lodash, subrayado y plano (paquete NPM).
En todos los casos, obtengo una lista más corta de lo que esperaba (porque solo obtengo los padres), o obtengo un objeto completamente aplanado con objetos delimitados por notación de puntos, lo cual es inútil para mí.
Sé que hay muchas preguntas y respuestas relacionadas con este tema, pero nada de lo que he visto coincide con mi caso de uso, y parece que no puedo entender el problema.
Aquí hay una muestra de mi estructura de datos:
const sampleData = { coyotes: '', armadillos: false, wombats: [''], geckos: 0, dogs: { beagle: '', bulldog: '' }, wolves: [ { type: '', color: '', range: '', status: { endangered: true, protected: false } } ], cats: {} }Esto es lo que (idealmente) quiero de vuelta:
result = {coyotes, armadillos, wombats, geckos, dogs, beagle, bulldog, wolves, type, color, range, status, endangered, protected, cats}Esta es la forma en que me gustaría llamar al método de aplanamiento:
flattenData(sampleData)Esto es lo que tengo hasta ahora:
const flattenData = (obj) => Object.assign( {}, ...(function _flatten (o) { return [].concat(...Object.keys(o) .map(k => typeof o[k] === 'object' ? _flatten(o[k]) : (Number([k]) !== 0 && { [k]: o[k] }) ) ) }(obj)) )...que produce:
{ "coyotes": "", "armadillos": false, "geckos": 0, "beagle": "", "bulldog": "", "type": "", "color": "", "range": "", "endangered": true, "protected": false }Como notará, faltan algunos padres (wombats, perros, lobos y estatus) y falta un objeto vacío (gatos).
Este no es el código más bonito que he escrito. lamentablemente lo consigue todo
const flattenData = (data) => { let results = []; const recursive = (data) => { Object.keys(data) .map(function (key) { results.push(key); recursive(data[key]); return data[key]; // This doesn't actually do anything... }); } recursive(data); return results; }; const value = flattenData(sampleData);Aquí hay una recursividad simple:
const deepKeys = (o) => Array .isArray (o) ? o .flatMap (deepKeys) : Object (o) === o ? Object .entries (o) .flatMap (([k, v]) => [k, ... deepKeys (v)]) : [] const sampleData = {coyotes: '', armadillos: false, wombats: [''], geckos: 0, dogs: {beagle: '', bulldog: ''}, wolves: [{type: '', color: '', range: '', status: {endangered: true, protected: false}}], cats: {}} console .log (deepKeys (sampleData)) .as-console-wrapper {max-height: 100% !important; top: 0}Necesitamos procesar un poco diferente para arreglos, objetos y otros tipos, pero cada uno es bastante simple.