Estoy tratando de encontrar una solución en Vanilla JS (sin usar bibliotecas de terceros) que verifique una entrada determinada y determine si está "vacía" o no.
Tengo el siguiente código y afirmaciones con las que me gustaría comparar. Cada caso de prueba tiene una respuesta esperada como comentario.
He probado varias funciones para 'comprobar en profundidad' estas afirmaciones en stackblitz, pero ninguna se ha acercado a obtener una cobertura completa.
https://stackblitz.com/edit/node-ksxnjm
const assert = require('assert'); function isEmpty(obj) { return Object.keys(obj).every((k) => !Object.keys(obj[k]).length); } const test1 = {}; // expect true const test2 = { some: 'value' }; // expect false const test3 = { some: {} }; // expect true const test4 = []; // expect true const test5 = [[]]; // expect true const test6 = { some: [] }; // expect true const test7 = { some: ['barry'] }; // expect false const test8 = { some: new Map() }; // expect true const test9 = { response: new Map([['body', new Map([['something', {}]])]]), }; // expect true const test10 = { response: '{"body":{"something":{}}}', }; // expect true const test11 = { something: { somethingElse: {} }, }; // expect true assert.strictEqual(isEmpty(test1), true); assert.strictEqual(isEmpty(test2), false); assert.strictEqual(isEmpty(test3), true); assert.strictEqual(isEmpty(test4), true); assert.strictEqual(isEmpty(test5), true); assert.strictEqual(isEmpty(test6), true); assert.strictEqual(isEmpty(test7), false); assert.strictEqual(isEmpty(test8), true); assert.strictEqual(isEmpty(test9), true); assert.strictEqual(isEmpty(test10), true); assert.strictEqual(isEmpty(test11), true);La función que creé funciona para la mayoría de estos casos de prueba, pero no para todos. Los que estoy luchando por cubrir son los objetos anidados y los objetos estriados. Estoy un poco perplejo en cuanto a cómo puedo proceder.
¿Cómo puedo verificar estos últimos casos de prueba?
EDITAR:
const test12 = { something: { somethingElse: { number: 1, someSet: new Set(['garry']), }, }, }; // should evaluate to false const test13 = new Map([ ['something', new Map([ ['somethingElse', new Map([ ['number', 1], ['someSet', new Set(['garry'])] ])] ])] ]); // should also evaluate to falsePuedes usar una función recursiva como esta:
values , obtenga los valores del objeto usando Array.from(o.values()) (Obtiene los valores de los objetos Set , Map y Array ) function isEmpty(o) { if (typeof o === "object") { let values = typeof o.values === "function" ? Array.from(o.values()) : Object.values(o) return values.every(isEmpty) } else { var parsed = parseJsonString(o) return parsed ? isEmpty(parsed) : !o } }; function parseJsonString(str) { try { return typeof str === 'string' && JSON.parse(str); } catch (e) { return ''; } }Aquí hay un fragmento ejecutable:
function isEmpty(o) { if (typeof o === "object") { let values = typeof o.values === "function" ? Array.from(o.values()) : Object.values(o) return values.every(isEmpty) } else { var parsed = parseJsonString(o) return parsed ? isEmpty(parsed) : !o } }; function parseJsonString(str) { try { return typeof str === 'string' && JSON.parse(str); } catch (e) { return ''; } } const test1 = {}; // expect true const test2 = { some: 'value' }; // expect false const test3 = { some: {} }; // expect true const test4 = []; // expect true const test5 = [[]]; // expect true const test6 = { some: [] }; // expect true const test7 = { some: ['barry'] }; // expect false const test8 = { some: new Map() }; // expect true const test9 = { response: new Map([['body', new Map([['something', {}]])]]), }; // expect true const test10 = { response: '{"body":{"something":{}}}', }; // expect true const test11 = { something: { somethingElse: {} }, }; // expect true const test12 = { something: { somethingElse: { number: 1, someSet: new Set(['garry']), } } }; // expect false const test13 = new Map([ ['something', new Map([ ['somethingElse', new Map([ ['number', 1], ['someSet', new Set(['garry'])] ])] ])] ]) // expect false console.log( [test1, test2, test3, test4, test5, test6, test7, test8, test9, test10, test11, test12, test13].map(isEmpty) );Creo que la única forma de resolver esto es usar Recursion
Primero debe decidir con qué datos está trabajando actualmente y luego ver si los datos tienen algo dentro. Si lo hacen, debe llamar a la función isEmpty nuevamente para verificar el tipo de datos internos y también si tienen algo dentro.
const isEmpty = value =>{ if(typeof value === 'object'){ if(Object.keys(value).length === 0) return true for (const property in value) { isEmpty(property) } } else if(typeof value === 'string'){ //check for string } //... //... //... //another types }