如何删除具有特定值的嵌套对象

How to delete nested objects with a particular value?

本文关键字:对象 嵌套 何删除 删除      更新时间:2023-09-26

给定嵌套对象:

var x = {
    'name': 'a',
    'testObj': {
        'blah': 8,
        'testObj2': { // delete this obj
            'blah2': 9,
            'blah3': 'c'
            }
        },
    'level': 1,
    'children': [{
        'name': 'b',
        'level': 2,
        'children': [{ // delete this obj
            'name': 'c',
            'level': 3
        }]}]
};

如何去删除一个嵌套的对象,如果它包含一个属性的值(在我的例子中,字符串'c')一个指定在一个函数?最终结果如下:

var x = {
    'name': 'a',
    'testObj': {
        'blah': 8,
        },
    'level': 1,
    'children': [{
        'name': 'b',
        'level': 2,
        'children': []}]
};
下面是目前为止的代码:
function recursiveIteration(obj, callback) {
    var k;
    if (obj instanceof Object) {
        for (k in obj){
            if (obj.hasOwnProperty(k)){
                recursiveIteration( obj[k], callback );  
            }                
        }
    } else {
        callback(obj); // this is the non-object val
    }
}
function deleteObjByValue(object, word) {
    return recursiveIteration(object, function(val) {
        if (word === val){
            // here I want to delete the nested object (not the whole object) that contains the property with this val assigned to it
        }else {
            return false;
        }
    });
}
deleteObjByValue(x, 'c');

首先遍历对象中的属性,检查是否应该删除它。如果应该,则返回true,以便调用函数可以删除它(因为您不能仅使用属性的值删除属性)。如果不应该删除,则循环遍历作为对象的属性以检查是否应该删除它们中的任何一个:

function deleteObjByValue(obj, value) {
    var k;
    for (k in obj){
        if (obj.hasOwnProperty(k)){
            if (obj[k] === value) {
                return true;
            }
        }                
    }
    for (k in obj){
        if (obj.hasOwnProperty(k) && obj[k] instanceof Object){
            if (deleteObjByValue(obj[k], value)) {
                delete obj[k];
            }
        }
    }
    return false;
}

演示:http://jsfiddle.net/hbHGM/

注意:如果main对象有一个与该值匹配的属性,则该函数不会删除任何内容。它只会返回true来表示整个物体应该消失。你可以这样处理它:

if (deleteObjByValue(x, 'c')) {
  x = null; // or whatever you want to do
}

您需要保持对对象的父对象的引用,以确定是否删除它。

这里有一个解决方案:

function deleteParentByValue(object, object_parent, value) {
    for (var x in object) {
        if (object.hasOwnProperty(x)) {
            if (typeof(object[x]) === 'object') {
                deleteParentByValue(object[x], object, value);
            } else {
                if (object[x] == value) {
                    for (var z in object_parent) {
                        if (object_parent[z] == object) {
                            if (object_parent instanceof Array) {
                                object_parent.splice(object_parent.indexOf(z), 1);
                            } else {
                                delete object_parent[z];
                            }
                        }
                    }
                    break;
                }
            }
        }
    }
}
function deleteObjByValue(object, word) {
    return deleteParentByValue(object, null, word);
}

从对象中删除属性的正确方法是调用delete函数。因此,您需要对代码进行一些重构,如(未经测试):

function recursiveIteration(parent, key, callback) {
    var obj = parent[key];
    var k;
    if (obj instanceof Object) {
        for (k in obj){
            if (obj.hasOwnProperty(k)){
                recursiveIteration( obj, k, callback );  
            }                
        }
    } else {
        callback(parent, key); // this is the non-object val
    }
}
function deleteObjByValue(object, word) {
    return recursiveIteration({object: object}, 'object', function(obj, key) {
        if (word === obj[key]){
            delete obj[key];
        }else {
            return false;
        }
    });
}
deleteObjByValue(x, 'c');