【问题标题】:Remove redundant properties from javascript object [duplicate]从javascript对象中删除冗余属性[重复]
【发布时间】:2011-12-28 18:03:41
【问题描述】:

可能重复:
How to remove Empty Properties from a multi depth JavaScript Object?

我想从一个对象中删除所有空属性(包括空字符串数组)。

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

例如我想从这个示例对象中删除整个分支“someObject”。

我应该如何使用 javascript 来做这件事?

我可以编写一个函数,递归遍历每个属性并删除空属性,但在上面的示例对象中,包含空字符串的数组不会被删除。

我应该很清楚,我正在寻找一个递归函数来处理比示例更复杂的对象。多层次的字符串、对象和数组任意组合。

问题在于递归函数从顶部开始,然后向下遍历对象。因此,一个非常长(并且是多余的)分支末尾的空字符串将被删除,但分支本身不会。

【问题讨论】:

    标签: javascript object recursion


    【解决方案1】:

    使用delete 关键字

    delete obj.someObject
    

    【讨论】:

    • 这相当于答案的 7%。
    • @Pointy:你是认真的吗?如果问题是“如何从对象中删除属性”,是的,但不是。
    • 谢谢托比,但我想你误会了。我难以遍历对象以删除空分支。如果我删除数组中的空字符串,数组本身现在是空的,但不会被删除。
    【解决方案2】:

    给定obj = (your object),使用delete obj.key从中删除key

    下面的代码在三遍中迭代对象的每个键。如果值是一个字符串,则如果它为空,则删除该键。如果 value 是一个数组,则迭代所有属性,只有当数组的所有成员都是空字符串时才删除 key。如果该值是一个对象,则如果对同一函数的递归调用(即支持任何深度的嵌套)返回一个没有键的对象,则该键将被删除。

    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);
    

    【讨论】:

    • 问题是这只适用于非常具体的浅层结构化对象。它不会对对象内部数组中的空字符串做任何事情
    • @tom:我在代码 sn-p 下方的评论解决了这个问题。也许我明天有机会尝试一下。
    • @Tom:我看到这个问题现在已经结束了,但是对于它的价值,我已经更新了我的答案。不过,链接问题中接受的答案更简洁...
    【解决方案3】:

    到达底部后,像这样遍历到根:

    (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;
        }
    })();
    

    测试“套件”:

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

    【讨论】:

    • Esailija,您最近的编辑是否改变了任何逻辑,还是只是风格?
    • @sandinymyjoints 我刚刚在上面运行了jsbeautifier... 伙计,我有一些可怕的缩进 =D
    猜你喜欢
    • 2019-08-27
    • 1970-01-01
    • 2010-09-17
    • 1970-01-01
    • 2019-07-23
    • 1970-01-01
    相关资源
    最近更新 更多