我有一个像这样的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")
有没有办法实现这个目标? 我不知道如何解决这个问题,因为我需要键的路径才能编辑树。
答案 0 :(得分: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"))
答案 1 :(得分:2)
您可以使用迭代和递归方法来搜索节点。如果发现停止迭代并返回。
此提案使用Array#some
,允许退出迭代。
如果存在来自实际node
的{{1}}且节点是数组,则此节点将被迭代。
node

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);

答案 2 :(得分:0)
这是一个简单的函数,用于查找与属性和值匹配的节点:
// 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);
然后简单地致电:
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)
示例代码段(检查id = 10的节点文本是否已更改):
@Input
public String getDistributionUrl() {
if (distributionUrl != null) {
return distributionUrl;
} else if (gradleVersion != null) {
return locator.getDistributionFor(gradleVersion, distributionType.name().toLowerCase()).toString();
} else {
return null;
}
}
答案 3 :(得分: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
已更新。