0
  1. i have one array of object

  2. need to remove empty array KEYS from that, which is nested

  3. here is the sample of array of object

  4. need to remove every fieldGroup array which is empty, with nested level

  5. how can i remove that using LODASH or omit-deep-lodash or any third party library

    [
    {
        "id": "sch_CV8e5NzZXwXhNp3TGnpryEmub2EC",
        "display_name": "test name",
        "connection_profile": {
            "type": "NAVIGATION",
            "access_methods": [
                {
                    "submit": true,
                    "ui_web": [
                        {
                            "id": "dslogo",
                            "fieldGroup": [] // need to remove all fieldGroup array which is empty array
                        },
                        {
                            "key": "label",
                            "fieldGroup": []
                        },
                        {
                            "key": "forgotpassword",
                            "fieldGroup": [ // need which has length
                                {
                                    "id": "forgotpassword",
                                    "key": "forgotpassword",
                                    "type": "link",
                                    "className": "d-flex flex-grow-1 justify-content-end",
                                    "templateOptions": {
                                        "label": "Need help?",
                                        "className": "pull-right",
                                        "hideRequiredMarker": true
                                    },
                                    "_id": "62b4665e9bba345e1937f669"
                                }
                            ]
                        }
                    ],
                    "navigator_method": "login",
                    "_id": "62b4665e9bba345e1937f663"
                }
            ]
        }
    },
    {
        "id": "sch_CV8e5NzZXwXhNp3TGnpryEmub2ED",
        "display_name": "test name 2",
        "connection_profile": {
            "type": "NAVIGATION",
            "access_methods": [
                {
                    "submit": true,
                    "ui_web": [
                        {
                            "key": "forgotpassword",
                            "fieldGroup": [
                                {
                                    "id": "forgotpassword 11",
                                    "key": "forgotpassword 11",
                                    "type": "link 11"
                                },
                                {
                                    "id": "forgotpassword 22",
                                    "key": "forgotpassword 22",
                                    "type": "link",
                                    "className": "d-flex flex-grow-1 justify-content-end"
                                }
                            ]
                        },
                        {
                            "id": "dslogo",
                            "fieldGroup": []
                        },
                        {
                            "key": "label",
                            "fieldGroup": []
                        }
                    ],
                    "navigator_method": "login",
                    "_id": "62b4665e9bba345e1937f663"
                }
            ]
        }
    }
    ]
    

how can i remove nested level empty array using lodash?

Radu Diță
  • 13,476
  • 2
  • 30
  • 34
Apurv Chaudhary
  • 1,672
  • 3
  • 30
  • 55
  • Try this one: https://stackoverflow.com/questions/286141/remove-blank-attributes-from-an-object-in-javascript – Krishna Jun 28 '22 at 16:04

8 Answers8

1

Why don't you just create a recursive function that walks the entire object and deletes entries when it finds fieldGroup as an empty array. Something like this:

let removeEmpty = (obj, key) => {
 if (!obj) {
    return
 }

 if (Array.isArray(obj)) {
    for( let i = 0; i<obj.length; i++) {
        removeEmpty(obj[i], key)
    }
 }
 if (typeof obj === "object") {
    if (obj[key]?.length === 0) {
        delete obj[key]
        return
    }

    const keys = Object.keys(obj);

    for (let i = 0; i<keys.length; i++) {
        removeEmpty(obj[keys[i]], key)
    }
 }
}

Then you can call the function like this:

removeEmpty(object, "fieldGroup ")

Notes:

  • This will modify the original object
  • It doesn't check that fieldGroup is an array, if you need this you can add an extra isArray(obj[key])
Radu Diță
  • 13,476
  • 2
  • 30
  • 34
1

First, I wouldn't advise you to use any external library. External libraries contain code that you could write as well, just written by other people, and while it would be a good idea to don't re-invent the wheel, it's not for granted that they will do exactly what you need, or that a function is provided for any need.

If performance is a concern, I would advise using JSON.stringify, since it's natively implemented by most browsers and won't require you to iterate over every node of your object explicitly.

The solution provided by holydragon is acceptable, but it won't guarantee you that if you have a string containing ,"fieldGroup":[] it won't be replaced as well. This could introduce bugs, even remotely.

Luckily, the function JSON.stringify contains an overload, it allows you to define a replacer in the second parameter. The replacer enables you to specify some logic about which node should and should not be included in the stringification process.

Said this, you can easily and performantly solve your problem like this:

obj = JSON.parse(JSON.stringify(obj, (key, value) => {
   if (key === 'fieldGroup' && JSON.stringify(value) === '[]') return undefined;
   return value;
}));

Example:

const obj = [
{
    "id": "sch_CV8e5NzZXwXhNp3TGnpryEmub2EC",
    "display_name": "test name",
    "connection_profile": {
        "type": "NAVIGATION",
        "access_methods": [
            {
                "submit": true,
                "ui_web": [
                    {
                        "id": "dslogo",
                        "fieldGroup": [] // need to remove all fieldGroup array which is empty array
                    },
                    {
                        "key": "label",
                        "fieldGroup": []
                    },
                    {
                        "key": "forgotpassword",
                        "fieldGroup": [ // need which has length
                            {
                                "id": "forgotpassword",
                                "key": "forgotpassword",
                                "type": "link",
                                "className": "d-flex flex-grow-1 justify-content-end",
                                "templateOptions": {
                                    "label": "Need help?",
                                    "className": "pull-right",
                                    "hideRequiredMarker": true
                                },
                                "_id": "62b4665e9bba345e1937f669"
                            }
                        ]
                    }
                ],
                "navigator_method": "login",
                "_id": "62b4665e9bba345e1937f663"
            }
        ]
    }
},
{
    "id": "sch_CV8e5NzZXwXhNp3TGnpryEmub2ED",
    "display_name": "test name 2",
    "connection_profile": {
        "type": "NAVIGATION",
        "access_methods": [
            {
                "submit": true,
                "ui_web": [
                    {
                        "key": "forgotpassword",
                        "fieldGroup": [
                            {
                                "id": "forgotpassword 11",
                                "key": "forgotpassword 11",
                                "type": "link 11"
                            },
                            {
                                "id": "forgotpassword 22",
                                "key": "forgotpassword 22",
                                "type": "link",
                                "className": "d-flex flex-grow-1 justify-content-end"
                            }
                        ]
                    },
                    {
                        "id": "dslogo",
                        "fieldGroup": []
                    },
                    {
                        "key": "label",
                        "fieldGroup": []
                    }
                ],
                "navigator_method": "login",
                "_id": "62b4665e9bba345e1937f663"
            }
        ]
    }
}
];

const cleanObj = JSON.parse(JSON.stringify(obj, (key, value) => {
   if (key === 'fieldGroup' && JSON.stringify(value) === '[]') return undefined;
   return value;
}));

console.log('Before: ', obj);
console.log('After: ', cleanObj);

Note: This solution will only work if the object has not a prototype, or a function attached. In other words, it will only work if the object is stringificable

  • 1
    This is new to me. It isn't even in the document of my w3school reference. I would prefer this method over mine if I had known it. Valuable information! – holydragon Jul 04 '22 at 10:55
0

First of all, you don't need a library for this task. I've adapted this solution to work for your use case. The function removeEmptyFieldGroup filters empty fieldGroup arrays, builds a new object and repeats the process recursively for nested objects.

const removeEmptyFieldGroup = (obj) => {
  return Object.entries(obj)
    .filter(([k, v]) => {
      if (k !== "fieldGroup") return true;
      if (!Array.isArray(v)) return true;
      return v.length > 0;
    })
    .reduce(
      (acc, [k, v]) => ({
        ...acc,
        [k]: v === Object(v) ? removeEmptyFieldGroup(v) : v,
      }),
      {}
    );
};

const dataCleaned = removeEmptyFieldGroup(data);

Another solution would be to use the package flat to flatten the object, evaluate if values of keys ending with fieldGroup are empty arrays and delete them.

const dataFlat = flatten(data);

Object.keys(dataFlat).forEach((key) => {
  if (!key.endsWith("fieldGroup")) return;
  if (Array.isArray(dataFlat[key]) && dataFlat[key].length === 0)
    delete dataFlat[key];
});

const dataCleaned = unflatten(dataFlat);
alexanderdavide
  • 1,487
  • 3
  • 14
  • 22
0

you don't need any lib for this, try this snippet for your desire output.

const newData = data.map(({connection_profile, ...rest}) => {
    if (connection_profile && connection_profile?.access_methods?.constructor === Array) {
        connection_profile.access_methods.forEach(m => m.ui_web = m.ui_web.filter(f => f.fieldGroup.length))
    }
    return {
       ...rest,
       connection_profile
    }
})
Mohit Sharma
  • 622
  • 6
  • 11
0

method to remove keys with empty array in deep nested objects []

function cleanObj(obj){
    function empty(e) {
          return Array.isArray(e) && e?.length == 0
        }
       if(typeof obj === "object"){
           Object.entries(obj).forEach(([k,v]) => {
               if (empty(v)){
                   console.log(k,v)
                   delete obj[k]
               } else if( typeof obj[k] === "object" ){
                   cleanObj(obj[k]) 
               }
           })  
       } else if (Array.isArray(obj)){
           for( let i = 0; i < obj.length; i++){
               cleanObj(obj[i])
           }
       } 
    return obj 
    }

let cleaned = cleanObj(obj); // return obj without all keys that have [] as value
araldhafeeri
  • 179
  • 9
0

This solution is short and easy to understand. Please try if it works for you performance-wise.

Concept

  1. Convert the whole array into a string using JSON.stringify().
  2. Replace all of the string in JSON format for the fieldGroup keys that have empty array using replaceAll().
  3. Convert the string back to array using JSON.parse().

Code

const data=[{id:"sch_CV8e5NzZXwXhNp3TGnpryEmub2EC",display_name:"test name",connection_profile:{type:"NAVIGATION",access_methods:[{submit:!0,ui_web:[{id:"dslogo",fieldGroup:[]},{key:"label",fieldGroup:[]},{key:"forgotpassword",fieldGroup:[{id:"forgotpassword",key:"forgotpassword",type:"link",className:"d-flex flex-grow-1 justify-content-end",templateOptions:{label:"Need help?",className:"pull-right",hideRequiredMarker:!0},"_id":"62b4665e9bba345e1937f669"}]}],navigator_method:"login","_id":"62b4665e9bba345e1937f663"}]}},{id:"sch_CV8e5NzZXwXhNp3TGnpryEmub2ED",display_name:"test name 2",connection_profile:{type:"NAVIGATION",access_methods:[{submit:!0,ui_web:[{key:"forgotpassword",fieldGroup:[{id:"forgotpassword 11",key:"forgotpassword 11",type:"link 11"},{id:"forgotpassword 22",key:"forgotpassword 22",type:"link",className:"d-flex flex-grow-1 justify-content-end"}]},{id:"dslogo",fieldGroup:[]},{key:"label",fieldGroup:[]}],navigator_method:"login","_id":"62b4665e9bba345e1937f663"}]}}];
let result = JSON.stringify(data);
result = result.replaceAll(',"fieldGroup":[]','');
result = JSON.parse(result);
console.log(result);
holydragon
  • 6,158
  • 6
  • 39
  • 62
0

Here is a generic implementation to omit any field with empty array as value from a nested object or array of objects

const data= [
{
    "id": "sch_CV8e5NzZXwXhNp3TGnpryEmub2EC",
    "display_name": "test name",
    "connection_profile": {
        "type": "NAVIGATION",
        "access_methods": [
            {
                "submit": true,
                "ui_web": [
                    {
                        "id": "dslogo",
                        "fieldGroup": [] // need to remove all fieldGroup array which is empty array
                    },
                    {
                        "key": "label",
                        "fieldGroup": []
                    },
                    {
                        "key": "forgotpassword",
                        "fieldGroup": [ // need which has length
                            {
                                "id": "forgotpassword",
                                "key": "forgotpassword",
                                "type": "link",
                                "className": "d-flex flex-grow-1 justify-content-end",
                                "templateOptions": {
                                    "label": "Need help?",
                                    "className": "pull-right",
                                    "hideRequiredMarker": true
                                },
                                "_id": "62b4665e9bba345e1937f669"
                            }
                        ]
                    }
                ],
                "navigator_method": "login",
                "_id": "62b4665e9bba345e1937f663"
            }
        ]
    }
},
{
    "id": "sch_CV8e5NzZXwXhNp3TGnpryEmub2ED",
    "display_name": "test name 2",
    "connection_profile": {
        "type": "NAVIGATION",
        "access_methods": [
            {
                "submit": true,
                "ui_web": [
                    {
                        "key": "forgotpassword",
                        "fieldGroup": [
                            {
                                "id": "forgotpassword 11",
                                "key": "forgotpassword 11",
                                "type": "link 11"
                            },
                            {
                                "id": "forgotpassword 22",
                                "key": "forgotpassword 22",
                                "type": "link",
                                "className": "d-flex flex-grow-1 justify-content-end"
                            }
                        ]
                    },
                    {
                        "id": "dslogo",
                        "fieldGroup": []
                    },
                    {
                        "key": "label",
                        "fieldGroup": []
                    }
                ],
                "navigator_method": "login",
                "_id": "62b4665e9bba345e1937f663"
            }
        ]
    }
}
]

const deleteFieldIfExistsAndEmpty = (item,fieldToDelete)=>{
 if(item.hasOwnProperty(fieldToDelete) && Array.isArray(item[fieldToDelete]) && item[fieldToDelete].length===0){
    delete item[fieldToDelete]
  }
  Object.values(item).forEach((value)=>{
    if (
    typeof value === 'object' &&
    !Array.isArray(value) &&
    value !== null
) {
    deleteFieldIfExistsAndEmpty(value,fieldToDelete)
} else if(Array.isArray(value)){
  omit_deep(value,fieldToDelete)
}
  })
}

const omit_deep =(objectData,fieldToDelete)=>{
if(Array.isArray(objectData)){
  objectData.forEach(item=>{
    deleteFieldIfExistsAndEmpty(item,fieldToDelete)
  })
} else if (
    typeof objectData === 'object' &&
    !Array.isArray(objectData) &&
    objectData !== null
) {
   deleteFieldIfExistsAndEmpty(objectData,fieldToDelete)
  }
}

omit_deep(data,"fieldGroup")
console.log(data)
0

One line code solution similar to Cristian's answer, in case you need to deal with {"fieldGroup": Null}.

const cleanEmptyObj = JSON.parse(JSON.stringify(data, (key, value) => {
       if (key === null ||  value=== "" ||Object.keys(value || {}).length === 0) return undefined;
       return value;
    }));

const data= [
{
    "id": "sch_CV8e5NzZXwXhNp3TGnpryEmub2EC",
    "display_name": "test name",
    "connection_profile": {
        "type": "NAVIGATION",
        "access_methods": [
            {
                "submit": true,
                "ui_web": [
                    {
                        "id": "dslogo",
                        "fieldGroup": [] // need to remove all fieldGroup array which is empty array
                    },
                    {
                        "key": "label",
                        "fieldGroup": []
                    },
                    {
                        "key": "forgotpassword",
                        "fieldGroup": [ // need which has length
                            {
                                "id": "forgotpassword",
                                "key": "forgotpassword",
                                "type": "link",
                                "className": "d-flex flex-grow-1 justify-content-end",
                                "templateOptions": {
                                    "label": "Need help?",
                                    "className": "pull-right",
                                    "hideRequiredMarker": true
                                },
                                "_id": "62b4665e9bba345e1937f669"
                            }
                        ]
                    }
                ],
                "navigator_method": "login",
                "_id": "62b4665e9bba345e1937f663"
            }
        ]
    }
},
{
    "id": "sch_CV8e5NzZXwXhNp3TGnpryEmub2ED",
    "display_name": "test name 2",
    "connection_profile": {
        "type": "NAVIGATION",
        "access_methods": [
            {
                "submit": true,
                "ui_web": [
                    {
                        "key": "forgotpassword",
                        "fieldGroup": [
                            {
                                "id": "forgotpassword 11",
                                "key": "forgotpassword 11",
                                "type": "link 11"
                            },
                            {
                                "id": "forgotpassword 22",
                                "key": "forgotpassword 22",
                                "type": "link",
                                "className": "d-flex flex-grow-1 justify-content-end"
                            }
                        ]
                    },
                    {
                        "id": "dslogo",
                        "fieldGroup": []
                    },
                    {
                        "key": "label",
                        "fieldGroup": [    {
                        "id": "dslogo",
                        "fieldGroup": null
                    } ]
                    }
                ],
                "navigator_method": "login",
                "_id": "62b4665e9bba345e1937f663"
            }
        ]
    }
}
]


    const cleanEmptyObj = JSON.parse(JSON.stringify(data, (key, value) => {
   if (key === null ||  value=== "" ||Object.keys(value || {}).length === 0) return undefined;
   return value;
}));
    
console.log(cleanEmptyObj);
Aiden Or
  • 70
  • 6