Home > Software design >  For IN Loop inside Map Javascript
For IN Loop inside Map Javascript

Time:11-10

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.

CodePudding user response:

The following function should do the job.

data.formGroups.map((formGroup) => {
  Object.keys(formGroup).forEach((key) => {
    if (formGroup[key] !== "") {
      formGroup[key.replace("dependence", "")] = formGroup[key];
    }
    delete formGroup[key];
  });
});

CodePudding user response:

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 }]

  • Related