Remove redundant properties from javascript object

2020-03-31 01:56发布

问题:

This question already has answers here:
Closed 8 years ago.

Possible Duplicate:
How to remove Empty Properties from a multi depth JavaScript Object?

I'd like to remove all empty properties (including arrays of empty strings) from an object.

{ "someString" : "some text", "someObject" : { "array" : [ "", "" ] } }

E.g. I'd like to remove the entire branch "someObject" from this example object.

How should I go about doing this with javascript?

I can write a function that iterates of over each property recursively and removes empty ones, but in the example object above the array containing empty strings would not be removed.

I should be clear, I am looking to write a recursive function that will handle far more complex objects than the example. Multiple levels of strings, objects and arrays in any combination.

The problem is that a recursive function starts at the top and works its way down through the object. So an empty string at the end of a very long (and otherwise redundant) branch, will be deleted but the branch itself wont.

回答1:

Given obj = (your object), use delete obj.key to delete key from it.

The code below iterates every key of the object in three passes. If the value is a string, the key is deleted if it's empty. If the value is an array, all properties are iterated, and the key is deleted only if all members of the array are empty strings. If the value is an object, the key is deleted if a recursive invocation of the same function (i.e. will support any depth of nesting) returns an object with no keys.

function removeEmptyStrings(obj) {
   for(var key in obj) {

      // value is empty string
      if(obj[key] === '') {
         delete obj[key];
      }

      // value is array with only emtpy strings
      if(obj[key] instanceof Array) {
         var empty = true;
         for(var i = 0; i < obj[key].length; i++) {
             if(obj[key][i] !== '') {
                empty = false;
                break;
             }
         }

         if(empty)
            delete obj[key];
      }

      // value is object with only empty strings or arrays of empty strings
      if(typeof obj[key] === "object") {
         obj[key] = removeEmptyStrings(obj[key]);

         var hasKeys = false;
         for(var objKey in obj[key]) {
            hasKeys = true;
            break;
         }

         if(!hasKeys)
            delete obj[key];
      }
   }

   return obj;
}

// invoke    
var test = { "someString" : "some text", "someObject" : { "array" : [ "", "" ] } };
removeEmptyStrings(test);


回答2:

After reaching bottom, just traverse back to the root like so:

(function () {
    Object.removeEmptiness = removeEmptiness;

    function isArray(obj) {
        return obj && Object.prototype.toString.call(obj) === "[object Array]" || false;
    }

    function isObject(obj) {
        return obj && typeof obj == "object" || false;
    }

    function removeEmptiness(root, undef) {
        var removeProps;
        removeProps = function (obj, key, parent) {
            var i, isFullyEmpty = true,
                value;
            if (isArray(obj)) {
                //.length not cached on purpose
                for (i = 0; i < obj.length; ++i) {
                    value = obj[i];
                    if (isObject(value)) {
                        removeProps(value, i, obj);
                        isFullyEmpty = false;
                    } else if (value === "" || value === undef) {
                        obj.splice(i--, 1);
                    } else {
                        isFullyEmpty = false;
                    }
                }
            } else {
                for (i in obj) {
                    value = obj[i];
                    if (isObject(value)) {
                        removeProps(value, i, obj);
                        isFullyEmpty = false;
                    } else if (value === "" || value === undef) {
                        delete obj[i];
                    } else {
                        isFullyEmpty = false;
                    }
                }
            }
            if (key !== undef && isFullyEmpty) {
                delete parent[key];
                removeProps(root);
            }
        };
        removeProps(root);
        return root;
    }
})();

Test "suite":

var obj = { "someString" : "some text", "someObject2" : {"k":"", "v": ["k"] }, "someArray3": [{}, ["","",""] ], "someObject" : { "array" : [ "", "", {"hello": ["",""] } ] } };
Object.removeEmptiness( obj );
console.log( JSON.stringify( obj ) );

//"{"someString":"some text","someObject2":{"v":["k"]}}"


回答3:

Use the delete keyword

delete obj.someObject