Json:编辑深层嵌套值

时间:2017-02-14 13:27:22

标签: javascript 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")

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

4 个答案:

答案 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已更新。