2017-02-14 74 views
1

我JSON像这样的数组:JSON:编辑嵌套很深的值

var tree = [ 
     { 
     text: "Parent 1", 
     id: 1, 
     nodes: [ 
      { 
      text: "Child 1", 
      id: 2, 
      nodes: [ 
       { 
       text: "Grandchild 1" 
       id: 3, 
       }, 
       { 
       text: "Grandchild 2" 
       id: 4, 
       nodes: [ 
        { 
        text: "Grandchild 3" 
        id: 10, 
        }, 
        { 
        text: "Grandchild 4" 
        id: 11, 
        nodes: [ 
         { 
         text: "Grandchild 5" 
         id: 12, 
         }, 
         { 
         text: "Grandchild 6" 
         id: 13, 
         } 
        ] 
        } 
       ] 
       } 
      ] 
      }, 
      { 
      text: "Child 2" 
      id: 5, 
      } 
     ] 
     }, 
     { 
     text: "Parent 2" 
     id: 6, 
     }, 
     { 
     text: "Parent 3" 
     id: 7, 
     }, 
     { 
     text: "Parent 4" 
     id: 8, 
     }, 
     { 
     text: "Parent 5" 
     id: 9, 
     } 
    ]; 

我试图创造条件,采取为参数树,ID和newText参数的函数,即将找到具有给定id的节点,用newText替换文本,并返回修改后的json。

例:

editTree(tree, 11, "Granchild 13435") 

有没有办法来实现这一目标? 我不知道如何解决这个问题,因为我需要密钥的路径才能编辑树。

+1

[没有这样的事情作为“JSON对象”](http://benalman.com/news/2010/03/theres-no-such-thing-as-a-json/) – Andreas

+0

@Andreas谢谢你为指出这 –

+0

试试这个答案:http://stackoverflow.com/questions/22222599/javascript-recursive-search-in-json-object – jonasfh

回答

2

您可以对此使用递归函数。

var tree = [{"text":"Parent 1","id":1,"nodes":[{"text":"Child 1","id":2,"nodes":[{"text":"Grandchild 1","id":3},{"text":"Grandchild 2","id":4,"nodes":[{"text":"Grandchild 3","id":10},{"text":"Grandchild 4","id":11,"nodes":[{"text":"Grandchild 5","id":12},{"text":"Grandchild 6","id":13}]}]}]},{"text":"Child 2","id":5}]},{"text":"Parent 2","id":6},{"text":"Parent 3","id":7},{"text":"Parent 4","id":8},{"text":"Parent 5","id":9}] 
 

 
function editTree(tree, id, val) { 
 
    for (var i in tree) { 
 
    if (i == 'id') { 
 
     if (tree[i] == id) { 
 
     tree.text = val 
 
     return 1; 
 
     } 
 
    } 
 
    if (typeof tree[i] == 'object') editTree(tree[i], id, val) 
 
    } 
 
    return tree; 
 
} 
 

 

 
console.log(editTree(tree, 11, "Granchild 13435"))

2

你可以使用迭代和递归方法用于搜索节点。如果发现停止迭代并返回。

此建议使用Array#some,允许退出迭代。

如果存在来自实际nodenode且该节点是一个数组,则该节点被迭代。

function editTree(tree, id, text) { 
 
    tree.some(function iter(o) { 
 
     if (o.id === id) { 
 
      o.text = text; 
 
      return true; 
 
     } 
 
     return Array.isArray(o.nodes) && o.nodes.some(iter); 
 
    }); 
 
} 
 

 
var tree = [{ text: "Parent 1", id: 1, nodes: [{ text: "Child 1", id: 2, nodes: [{ text: "Grandchild 1", id: 3, }, { text: "Grandchild 2", id: 4, nodes: [{ text: "Grandchild 3", id: 10, }, { text: "Grandchild 4", id: 11, nodes: [{ text: "Grandchild 5", id: 12, }, { text: "Grandchild 6", id: 13, }] }] }] }, { text: "Child 2", id: 5, }] }, { text: "Parent 2", id: 6, }, { text: "Parent 3", id: 7, }, { text: "Parent 4", id: 8, }, { text: "Parent 5", id: 9, }]; 
 

 
editTree(tree, 11, "Granchild 13435");  
 
console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }

0

下面是一个简单的函数来找到匹配属性和值的节点:

function findNode(nodes, prop, value) { 
    if(!value || !(nodes instanceof Array)) return; 
    for(var i=0; i<nodes.length; i++) { 
     if(node = (value == nodes[i][prop]) ? nodes[i] : findNode(nodes[i]['nodes'], value)) { 
     return node; 
     } 
    } 
} 

然后,只需拨打:

// Find node with id = 10 
var node = findNode(tree, 'id', 10); 
if(node) { 
    // Yeah! we found it, now change its text 
    node['text'] = 'Changed!'; 
} 

// Ensure tree has been updated 
console.log(tree); 

示例代码段(请检查id = 10的节点文本是否已更改):

var tree=[{text:"Parent 1",id:1,nodes:[{text:"Child 1",id:2,nodes:[{text:"Grandchild 1",id:3},{text:"Grandchild 2",id:4,nodes:[{text:"Grandchild 3",id:10},{text:"Grandchild 4",id:11,nodes:[{text:"Grandchild 5",id:12},{text:"Grandchild 6",id:13}]}]}]},{text:"Child 2",id:5}]},{text:"Parent 2",id:6},{text:"Parent 3",id:7},{text:"Parent 4",id:8},{text:"Parent 5",id:9}]; 
 

 

 
function findNode(nodes, prop, value) { 
 
    if(!value || !(nodes instanceof Array)) return; 
 
    for(var i=0; i<nodes.length; i++) { 
 
     var node = (value == nodes[i][prop]) ? nodes[i] : findNode(nodes[i]['nodes'], prop, value); 
 
     if(node) { 
 
     return node; 
 
     } 
 
    } 
 
} 
 

 
var node = findNode(tree, 'id', 10); 
 
if(node) { 
 
    node['text'] = 'Changed!'; 
 
} 
 

 
console.log(tree)

0

我已经创建了一个使用递归的步行路程,其方法之一是正是你需要的库。

https://github.com/dominik791/obj-traverse

使用findFirst()方法。第一个参数是一个根对象,而不是数组,所以你应该首先创建:

var tree = { 
    text: 'rootObj', 
    nodes: [ 
    { 
    text: 'Parent 1', 
    id: 1, 
    nodes: [ 
     { 
     'text': 'Child 1', 
     id: 2, 
     nodes: [ ... ] 
     }, 
     { 
     'name': 'Child 2', 
     id: 3, 
     nodes: [ ... ] 
     } 
    ] 
    }, 
    { 
    text: 'Parent2', 
    id: 6 
    } 
}; 

然后:

var objToEdit = findFirst(tree, 'nodes', { id: 11 }); 

现在objToEdit是要编辑的对象的引用。所以你可以:

objToEdit.text = 'Granchild 13435'; 

和你tree被更新。