6

在我的应用程序中,我基于来自服务器的 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 检索到对象的路径。

4

5 回答 5

9

看到这个小提琴:http: //jsfiddle.net/2Dvws/

它将通过 ID 查找对象。并推新子。由于 Javascript 中的每个对象都是引用,因此您可以将其作为 var 返回。

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 的孩子将有 1 个 id 为 1111 的孩子 ​</p>

于 2012-10-15T16:41:33.793 回答
2

我假设 id 由 parent-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;
于 2012-10-15T16:22:13.340 回答
2

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;
          }
        }
      }
    }
  };
于 2016-06-17T19:11:35.543 回答
0

这个怎么样。

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: []
            });
        }
    }
}
于 2012-10-15T16:13:13.690 回答
0

这是使用object-scan的解决方案。使用库应该使其更具可读性和可维护性。

// const objectScan = require('object-scan');

const insert = (haystack, parentId, node) => objectScan(['**.id'], {
  abort: true,
  rtn: 'bool',
  filterFn: ({ value, parent }) => {
    if (value === parentId) {
      parent.children.push(node);
      return true;
    }
    return false;
  }
})(haystack);

const obj = { 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: [] } ] };

console.log(insert(obj, 11, { name: "grandchild three", id: 113, children: [] })); // true iff inserted
// => true

console.log(obj);
// => { 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: 'grandchild three', id: 113, children: [] } ] }, { name: 'child two', id: 12, children: [] } ] }
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/object-scan@13.8.0"></script>

免责声明:我是对象扫描的作者

于 2020-11-18T06:13:24.487 回答