Given the current example array of objects:
const data = { ...otherData, formGroups: [{roldependence: "a", rol2dependence: "", rol3dependence: "b"},{roldependence: "", rol2dependence: "1", rol3dependence: ""}] }
I need to iterate through the objects and do 3 things: Delete empty objects Delete empty keys Modify key names and delete the word “dependence”
The new array should look like:
console.log(data.formGroups) // [{ rol: "a", rol3: "b" }, { rol2: 1 }]
What I tried so far:
const newData = { ...data }; if (newData.formGroups) { newData = { ...newData, formGroups: newData.formGroups .filter((element) => { // Removing empty objects if (Object.keys(element).length !== 0) { return true; } return false; }) .map((element) => { const newElem = { ...element }; for (let key in newElem) { // Remove dependence word if (key.includes("dependence")) { newElem[key.replace(/dependence([0-9]+)$/, "")] = newElem[key]; delete newElem[key]; } // Remove empty keys if (!newElem[key]) { delete newElem[key]; } } return newElem; }), }; //Then the parsed "newData" will be used for something else...
Is there an elegant way to do this? I feel I’m mutating state in ways I shouldn´t.
Advertisement
Answer
The following code uses the side-effect-free style frequently found in React/Redux codebases. You could also implement this in a more performant fashion by making in-place changes.
noFalsyProps
takes an array of entries (from an Object.entries
call) and eliminates all properties with a falsy (eg. empty string) value.
correctPropNames
takes an array of entries and ensures instances of the string 'dependence'
are removed.
transform
uses Arrray#reduce
to remove all objects with no own properties; for the remainder it transforms the objects using noFalsyProps
and correctPropNames
.
const noFalsyProps = (entries) => entries.reduce((acc, [k, v]) => v ? [...acc, [k, v]] : acc, []) const correctPropNames = (entries) => entries.map(([k, v]) => [k.replace(/dependence/g, ''), v]) const transform = (data) => data.reduce((acc, c) => { const transformed = correctPropNames(noFalsyProps(Object.entries(c))) return transformed.length ? [...acc, Object.fromEntries(transformed)] : acc }, []) const data = [{ roldependence: "a", rol2dependence: "", rol3dependence: "b" }, { roldependence: "", rol2dependence: "1", rol3dependence: "" }] console.log(transform(data)) // [{ rol: "a", rol3: "b" }, { rol2: 1 }]