Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/455.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用父id向嵌套javascript对象添加对象_Javascript_Json_Rest - Fatal编程技术网

如何使用父id向嵌套javascript对象添加对象

如何使用父id向嵌套javascript对象添加对象,javascript,json,rest,Javascript,Json,Rest,在我的应用程序中,我基于来自服务器的JSON响应创建了一个JavaScript对象,如下所示: { name: "root", id: 1, children: [ { name: "child one", id: 11, children: [ {name: "grand child 1", id: 111, children: []}, {name: "grand child 2", id: 112, chi

在我的应用程序中,我基于来自服务器的JSON响应创建了一个JavaScript对象,如下所示:

{
  name: "root",
  id: 1,
  children: [
    {
      name: "child one",
      id: 11,
      children: [
       {name: "grand child 1", id: 111, children: []},
       {name: "grand child 2", id: 112, children: []}
      ]
   },
   {
     name: "child two",
     id: 12,
     children: []
   }
  ]
}
我创建一个新节点,例如:

 {name: "grandchild three", id: 113, children:[]}
考虑到这一点,我如何将这个新孙子添加到其id为11的父级?请注意,我不知道到
id==11的节点的静态路径,因此我想知道如何在知道它的
id
的情况下获得该节点

编辑:请注意,真实情况下的id不会对对象的路径进行编码。我创建了这个简单的示例来演示我正在处理的数据结构。但是在我的实际应用程序中,我无法使用对象的id检索到该对象的路径。

如何

for(var a = 0; a < object.length; a++) {
    for(var b = 0; b < obj.children.length; b++) {
        if(object[a].children[b].id == 11) {
           object[a].children[b].children.push({
                name: "grandchild three", 
                id: 113, 
                children: []
            });
        }
    }
}
for(var a=0;a
我假设id由父id加上子数组中的索引(1到9)组成?然后你可以这样说:

var rootobj = {…};
var newnode = {name: "grandchild three", id: 113, children:[]};

var id = ""+newnode.id;
var cur = [rootobj];
for (var i=0; i<id.length-i; i++)
    cur = cur[id.charAt(i)-1].children;
cur[id.charAt(i)-1] = newnode;
var rootobj={…};
var newnode={name:“孙子三号”,id:113,子节点:[]};
var id=”“+newnode.id;
var cur=[rootobj];
对于(var i=0;i参见此小提琴:

它将按ID查找一个对象,并推送新的子对象。因为Javascript中的每个对象都是引用,所以可以将其作为变量返回

var ob = {
    name: "root",
    id: 1,
    children: [
        {
        name: "child one",
        id: 11,
        children: [
            {
            name: "grand child 1",
            id: 111,
            children: []},
        {
            name: "grand child 2",
            id: 112,
            children: []}
        ]},
    {
        name: "child two",
        id: 12,
        children: []}
    ]
};
返回找到的元素的函数。将查找所有子元素

function findObjectById(root, id) {
    if (root.children) {
        for (var k in root.children) {
            if (root.children[k].id == id) {
                return root.children[k];
            }
            else if (root.children.length) {
                return findObjectById(root.children[k], id);
            }
        }
    }
};

var bla = findObjectById(ob, 111);

console.log(bla);
bla.children.push({
        name: "child x",
        id: 1111,
        children: []
});
console.log(ob);
输出是id为111的子级将有一个id为1111的子级

Niels的答案是一个很好的开始,但并没有完全遍历树(例如,如果您要查找的节点是根的第二个子节点的子节点,它将中断)。如果根是您要查找的id,它也将中断。以下是我的改进:

  function findObjectByID(root, id) {
    if (root.name == id){
      return root;
    }
    if (root.children) {
      for (var k in root.children) {
        if (root.children[k].name == id) {
          return root.children[k];
        }
        else if (root.children[k].children) {
          result = findObjectByID(root.children[k], id);
          if (result) {
            return result;
          }
        }
      }
    }
  };
这是一个使用的解决方案。使用库应该使它更可读和更易于维护

//const objectScan=require('object-scan');
const insert=(haystack,parentId,node)=>objectScan(['**.id']{
中止:对,
rtn:‘bool’,
filterFn:({value,parent})=>{
如果(值===父ID){
父.children.push(节点);
返回true;
}
返回false;
}
})(干草堆);
const obj={name:'root',id:1,子项:[{name:'child one',id:11,子项:[{name:'grand child 1',id:111,子项:[]},{name:'grand child 2',id:112,子项:[]},{name:'child two',id:12,子项:[]};
log(insert(obj,11,{name:“孙子三号”,id:113,children:[]}));//插入true
//=>正确
控制台日志(obj);
//=>{name:'root',id:1,子项:[{name:'child one',id:11,子项:[{name:'grand child 1',id:111,子项:[]},{name:'grand child 2',id:112,子项:[]},{name:'sunder three',id:113,子项:[]},{name:'child two',id:12,子项:[]}
。作为控制台包装{最大高度:100%!重要;顶部:0}

对象。子对象[0]。子对象。推送(newobject)
其中object是您的原始对象,newobject是您的新节点。感谢您的快速响应。但是,如果我只有父id,我如何才能找到对象的路径?这会遍历树吗?它看起来只搜索一个节点的子节点。问题是我不知道我的节点有多深,我只有它的id。向上它支持遍历树。好的,我现在明白了。所以我需要在树上做嵌套搜索,找到我要插入的节点,然后添加到它的子节点。但是为了得到完整和正确的答案,我认为你应该更新你的答案,使用递归或其他形式的树搜索算法当前表单假设我的数据结构只有两层。这不能用任何叶子都能生长的嵌套树来假设。再次感谢!@Austin:这并不是真的遍历树,而是只遍历根节点的子节点。没问题。下一次,这将有助于在您的问题中更加具体并包括在内。@Berg我在评论之后意识到了这一点。我的意思是在子节点之间循环。该死,你太聪明了!不,我不能假设id是那种形式。我只是做了一个简单的例子来帮助讨论这个问题。我正在使用的真实API中的id是独立于对象路径生成的。好吧,那么你怎么知道对象的路径呢一个节点?或者你根本不知道,并且需要为你知道其
id
的父节点做一个测试?这应该不会太难。谢谢!这是考虑我的嵌套树结构的唯一答案。你必须注意,函数也可以返回
null
,然后你不能执行
bla.children.push
,因为
bla
NULL