Delete all obj props depending on children?

Hey everyone, have a problem I’m not quite sure how to solve so I figured maybe I can reach out and someone else has a good idea on what can be done here.

I have a nested object with each key being a class and the value being an object of children and attributes. If the key (className) in the object doesn’t have any children or attributes, it should be deleted. The issue is that if I check the last level in the nested object to delete the property, I’m not sure how to recursively track back up the object to delete every prop based on the children that need to be deleted.

For example:

{
   ".tester-class": {
      "children": {
         ".tester-child": {
            "children": {},
            "attributes": {}
         },
         ".tester-child-2": {
            "children": {},
            "attributes": {}
         }
      },
      "attributes": {}
   },
   ".another": {
      "children": {},
      "attributes": {}
   },
   "media-class": {
      "children": {
         ".tester-class": {
            "children": {
               ".media-child": {
                  "children": {
                     ".nested-3-child": {
                        "children": {
                           ".nested-4-child": {
                              "children": {},
                              "attributes": {}
                           }
                        },
                        "attributes": {}
                     }
                  },
                  "attributes": {
                     "color": "navy"
                  }
               }
            },
            "attributes": {}
         }
      },
      "attributes": {}
   }
}

In this example above, the top level .tester-class and .another keys should be deleted because none of their children have attributes or children, so they should be removed, but because of the color: navy attribute on .media-child, that should stay. So .media-class > .tester-class (second one), > & .media-child should persist, but .nested-3-child & .nested-4-child should be deleted because they are empty.

Theoretically, if the attribute color: navy on .media-child did not exist and was just an empty {}, this entire object would be {} because no children have attributes or children.

I first thought I could use recursion by digging all the way down until no more children exist and collect the props along the way to track back up the tree, but I am really confused here.

Does anyone have a good idea how this could be done? I’m not looking for easy answers or code, but just a brainstorming buddy to push me in the right direction on the easiest way possible for this.

Hey! Yes, if the property doesn’t have children but it does contain attributes, the prop needs to stay with every parent that it is nested within (because the parents have children that dig in the nested object).

A property should only be deleted from the entire object if it has no children and attributes.

The most deeply nested property in the object should go down to the last property with attributes. To reference the example above, .tester-class & .another at the top level and all their children would be deleted from the object, however, .media-class would stay as the first level prop in the object because it’s grandchild at .media-class > .tester-class > .media-child has an attribute of color: navy. Because nested-3-child & nested-4-child don’t have children or attributes, they would also be deleted from the object.

Alternatively, if the attribute on .media-child of color: "navy" did not exist, the return of this function that digs into this object would return {} because no prop has attributes.

Hope this makes sense and I appreciate your time.

Edit: I’ve considered looking into ways like this: javascript - Remove empty & null values from nested object (ES6) - Clean nested Objects - Stack Overflow

I have also tried with recursion and keeping track of every key that you dig into and it’s children, to then recursively delete by the most deeply nested prop and work your way up to effectively traverse each child.

I cannot believe it but this might be it. I need to refactor slightly but I wonder if any bugs this might introduce

cleanObject = function(object) {
    Object
        .entries(object)
        .forEach(([k, v]) => {
            if (v && typeof v === 'object')
                cleanObject(v);
            if (v && 
                typeof v === 'object' && 
                !Object.keys(v).length || 
                v === null || 
                v === undefined ||
                v.length === 0 
            ) {
                if (Array.isArray(object))
                    object.splice(k, 1);
                else if (!(v instanceof Date))
                    delete object[k];
            }
        });
    return object;
}

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.