在不知道深度或父属性的情况下从对象中删除属性

Delete property from object without knowing depth or parent properties

本文关键字:属性 对象 删除 情况下 深度 不知道      更新时间:2023-09-26

我目前有一个深度未知的嵌套javascript对象。该对象是纯动态生成的,所以我不知道要删除的属性的父对象的名称(如果必须,我可以修改一些内容来获得它们,但我正在努力避免这种情况)。

我目前有一个名为search_tree(name)的函数,它搜索对象的所有属性,直到找到属性 name : "name" ,然后返回该对象,以便在树的那个位置添加数据。

然而,我现在需要从树中删除该对象,并且还没有让它工作。我试过:

obj = search_tree(name);
delete obj;

我假设这不起作用,因为obj实际上不是树中的对象,而是对它的引用?

delete search_tree(name);

也没有结果。可以这样做吗?还是我需要更改search_tree函数以某种方式返回遗产(或者只是制作一个不同的遗产)?感谢

search_tree中的代码

function search_tree(element, matchingName){
     if(element.name == matchingName){
          return element;
      }else if (element.children != null){
            var result = null;
            for(var child in element.children){
                 result = searchTree(element.children[child], matchingName);
            }
            return result;
      } else {
            return null;
      }
}

刚刚实现的这个功能可能有点不清楚,没有解释。树中的每个对象都有一个名为"children"的子对象,其中将存储任意数量的其他对象。我添加了额外的"子对象"层,因为这些对象通常有子对象,我不想作为树的一部分进行搜索。元素是通过搜索的对象

是否要从树中删除对象?这就是你想要做的吗?

如果是,则将树的"父"节点存储在搜索中。编写第二个函数——可能是prune_tree,在其中传递父对象和对象(或同时作为属性的对象),然后执行for。。。寻找父母。如果parent[key]===object,则删除parent[key];

现在,您有了一个完整的树,其中特定的父对象不再包含该对象(或者您应该包含)。

假设search_tree应该是递归的,那么再给它一个参数(parent),您可以为每个深度级别提供一次参数(每个子级都有相同的父级)。一定要考虑到父项是根(因此没有父项)。当你找到你想要杀死的物体时,return { object : objectNode, parent : parentNode };

把它放进你的修剪函数中。对parentNode的引用意味着,当您删除parentNode.objectNode时,它将从树中删除(因为它毕竟只是一个引用)。

编辑:

基于以上内容:

function prune_tree (parent, child) {
    var key = "";
    for (key in parent) { if (parent.hasOwnProperty(key) && parent[key] === child) {
        delete parent[key];
    }
}

function search_tree (name, element, parent) {
    var key = "";
    if (element.name === name) {
        return prune_tree(parent, element);
    } else if (!element.children) {
        return null;
    } else {
        parent = element.children;
        for (key in children) { if (children.hasOwnProperty(key) {
            return search_tree(name, children[key], parent);
        }}
    }
}

当你递归时,我不能100%确定你实际在做什么(比如你是否依赖于一个特定的返回值,或者其他什么……我甚至不知道在不同的分支上是否有多个可能具有相同名称的对象,包括根节点)。

但像我在那里得到的东西应该会再次出现在你的树上。它将parent设置为element.children(存储子对象的位置),然后循环遍历子对象中的每个对象以再次调用函数,并将parent传递到下一个集合。所以element将是一个子元素,而parent将是保存它的children对象

如果element.namename完全匹配,则调用单独的函数prune_tree,并将保存的parent元素和当前子element传递给它。

prune_tree内部,只需遍历parent的键,直到找到要查找的子element。然后delete将其从父对象中删除。

这里不应该有任何意外,而且这组特定的函数可能会一直运行,直到访问了每个分支上的每个节点。。。因此,如果你有超过2000个节点,你可能需要考虑将其分解成块,否则会破坏一些浏览器的调用堆栈。假设你只有1000个或更少的节点,或者你只针对具有更大堆栈的浏览器,这应该会修剪所有具有相同名称的节点。

同样,这一切都取决于这是否是你的预期结果,或者你是否依赖于获得返回值,用它们做点什么,或者如果你只是想激发它,把它传递给树根,并期望函数净化树枝。

我也不确定你是想对修剪过的物体做点什么,还是只是为了让一棵树摆脱"名字"的暴政。