代码之家  ›  专栏  ›  技术社区  ›  aloisdg

如何将此数组映射到嵌套对象树?

  •  0
  • aloisdg  · 技术社区  · 6 年前

    我正在尝试在平面数组上创建树基。我的输入没有任何类型的父ID。每个元素都使用一个ID,该ID是一种具有此格式的路径。 ancestor(n+1)-ancestor1-Grandparent-parent-id 等。

    例如,当输入为

    [{"id":"1","children":[]},{"id":"1-1"}]
    

    那么输出应该是

    [{"id":"1","children":[{"id":"1-1"}]}]
    

    并给出

    [
      {
        "id": "1",
        "children": []
      },
      {
        "id": "1-1",
        "children": []
      },
      {
        "id": "1-1-1"
      },
      {
        "id": "1-2"
      },
      {
        "id": "2",
        "children": []
      },
      {
        "id": "2-1"
      }
    ]
    

    然后

    [{
        "id": "1",
        "children": [
          {
            "id": "1-1",
            "children": [
              {
                "id": "1-1-1"
              }
            ]
          },
          {
            "id": "1-2"
          }
        ]
      },
      {
        "id": "2",
        "children": [
          {
            "id": "2-1"
          }
        ]
      }
    ]
    

    我的当前代码:

    let list = [{
        "name": "Europe",
        "employeeCount": 1,
        "children": [],
        "id": "1"
      },
      {
        "name": "France",
        "employeeCount": 1,
        "children": [],
        "id": "1-1"
      },
      {
        "name": "Paris",
        "employeeCount": 1,
        "children": [],
        "id": "1-1-1"
      },
      {
        "name": "Foo Bar",
        "isInactive": false,
        "id": "1-1-1-27"
      }
    ]
    
    // I try this but I am not sure how to loop...
    function buildTree(list) {
      let tree = []
      for (var i = 0; i < list.length; i++) {
    
        if (!list[i].id.includes('-')) {
          tree.push(list[i]);
        } else {
          tree[tree.length - 1].children.push(list[i]);
        }
      }
      return tree;
    }
    
    
    let tree = buildTree(list)
    
    console.log(tree[0].children[0].children[0] === "Paris")

    相关: How to efficiently build a tree from a flat structure?

    1 回复  |  直到 6 年前
        1
  •  0
  •   aloisdg    6 年前

    由于对数组进行了排序,因此可以使用递归函数来实现它:

    const delimiter = '-';
    const delimiterCount = x => x.id.split('').reduce((acc, c) => acc + (c === delimiter), 0);
    
    
    function descend(tree, node, count) {
    	if (count == 0) {
    		tree.push(node);
    		return;
    	}
    
    	return descend(tree[tree.length - 1].children, node, count - 1);
    }
    
    function buildTree(list){
    	let tree = []
    	for (var i = 0; i < list.length; i++) {
    		let count = delimiterCount(list[i]);
    
    		descend(tree, list[i], count);
    	}
    	return tree;
    }
    

    以及一些“原始”单元测试:

    {
    let actual = buildTree([{"id":"1","children":[]},{"id":"1-1","children":[]},{"id":"1-1-1","children":[]},{"id":"1-1-1-1","children":[]},{"id":"1-1-1-1-1"}])
    let expected = [{"id":"1","children":[{"id":"1-1","children":[{"id":"1-1-1","children":[{"id":"1-1-1-1","children":[{"id":"1-1-1-1-1"}]}]}]}]}];
    let b = JSON.stringify(actual) === JSON.stringify(expected);
    if (!b) {console.log("expected:\n" + JSON.stringify(expected, null, 2));console.log("actual:\n" + JSON.stringify(actual, null, 2))}
    else console.log(true);
    }
    {
    let actual = buildTree([{"id":"1","children":[]},{"id":"1-1","children":[]},{"id":"1-1-1","children":[]},{"id":"1-1-1-1"}])
    let expected = [{"id":"1","children":[{"id":"1-1","children":[{"id":"1-1-1","children":[{"id":"1-1-1-1"}]}]}]}];
    let b = JSON.stringify(actual) === JSON.stringify(expected);
    if (!b) {console.log("expected:\n" + JSON.stringify(expected, null, 2));console.log("actual:\n" + JSON.stringify(actual, null, 2))}
    else console.log(true);
    }
    {
    let actual = buildTree([{"id":"1","children":[]},{"id":"1-1","children":[]},{"id":"1-1-1"},{"id":"1-2","children":[]},{"id":"1-2-1"},{"id":"2","children":[]},{"id":"2-1"}])
    let expected = [{"id":"1","children":[{"id":"1-1","children":[{"id":"1-1-1"}]},{"id":"1-2","children":[{"id":"1-2-1"}]}]},{"id":"2","children":[{"id":"2-1"}]}];
    let b = JSON.stringify(actual) === JSON.stringify(expected);
    if (!b) {console.log("expected:\n" + JSON.stringify(expected, null, 2));console.log("actual:\n" + JSON.stringify(actual, null, 2))}
    else console.log(true);
    }
    {
    let actual = buildTree([{"id":"1","children":[]},{"id":"1-1","children":[]},{"id":"1-1-1"},{"id":"1-2"},{"id":"2","children":[]},{"id":"2-1"}])
    let expected = [{"id":"1","children":[{"id":"1-1","children":[{"id":"1-1-1"}]},{"id":"1-2"}]},{"id":"2","children":[{"id":"2-1"}]}];
    let b = JSON.stringify(actual) === JSON.stringify(expected);
    if (!b) {console.log("expected:\n" + JSON.stringify(expected, null, 2));console.log("actual:\n" + JSON.stringify(actual, null, 2))}
    else console.log(true);
    }
    {
    let actual = buildTree([{"id":"1","children":[]},{"id":"1-1","children":[]},{"id":"1-1-1"},{"id":"2","children":[]},{"id":"2-1"}])
    let expected = [{"id":"1","children":[{"id":"1-1","children":[{"id":"1-1-1"}]}]},{"id":"2","children":[{"id":"2-1"}]}];
    let b = JSON.stringify(actual) === JSON.stringify(expected);
    if (!b) {console.log("expected:\n" + JSON.stringify(expected, null, 2));console.log("actual:\n" + JSON.stringify(actual, null, 2))}
    else console.log(true);
    }
    {
    let actual = buildTree([{"id":"1","children":[]},{"id":"1-1","children":[]},{"id":"1-1-1"},{"id":"2","children":[]}])
    let expected = [{"id":"1","children":[{"id":"1-1","children":[{"id":"1-1-1"}]}]},{"id":"2","children":[]}];
    let b = JSON.stringify(actual) === JSON.stringify(expected);
    if (!b) {console.log("expected:\n" + JSON.stringify(expected, null, 2));console.log("actual:\n" + JSON.stringify(actual, null, 2))}
    else console.log(true);
    }
    {
    let actual = buildTree([{"id":"1","children":[]},{"id":"1-1","children":[]},{"id":"1-1-1"},{"id":"1-1-2"}])
    let expected = [{"id":"1","children":[{"id":"1-1","children":[{"id":"1-1-1"},{"id":"1-1-2"}]}]}];
    let b = JSON.stringify(actual) === JSON.stringify(expected);
    if (!b) {console.log("expected:\n" + JSON.stringify(expected, null, 2));console.log("actual:\n" + JSON.stringify(actual, null, 2))}
    else console.log(true);
    }
    {
    let actual = buildTree([{"id":"1","children":[]},{"id":"1-1","children":[]},{"id":"1-1-1"}])
    let expected = [{"id":"1","children":[{"id":"1-1","children":[{"id":"1-1-1"}]}]}];
    let b = JSON.stringify(actual) === JSON.stringify(expected);
    if (!b) {console.log("expected:\n" + JSON.stringify(expected, null, 2));console.log("actual:\n" + JSON.stringify(actual, null, 2))}
    else console.log(true);
    }
    {
    let actual = buildTree([{"id":"1","children":[]},{"id":"1-1"},{"id":"2","children":[]},{"id":"2-1"}])
    let expected = [{"id":"1","children":[{"id":"1-1"}]},{"id":"2","children":[{"id":"2-1"}]}];
    let b = JSON.stringify(actual) === JSON.stringify(expected);
    if (!b) {console.log("expected:\n" + JSON.stringify(expected, null, 2));console.log("actual:\n" + JSON.stringify(actual, null, 2))}
    else console.log(true);
    }
    {
    let actual = buildTree([{"id":"1","children":[]},{"id":"1-1"},{"id":"1-2"}])
    let expected = [{"id":"1","children":[{"id":"1-1"},{"id":"1-2"}]}];
    let b = JSON.stringify(actual) === JSON.stringify(expected);
    if (!b) console.log(JSON.stringify(actual, null, 2))
    else console.log(true);
    }
    {
    let actual = buildTree([{"id":"1","children":[]},{"id":"1-1"}])
    let expected = [{"id":"1","children":[{"id":"1-1"}]}];
    let b = JSON.stringify(actual) === JSON.stringify(expected);
    if (!b) console.log(JSON.stringify(actual, null, 2))
    else console.log(true);
    }
    {
    let actual = buildTree([{id: "1","children":[]}, {id: "2","children":[]}])
    let expected = [{"id":"1","children":[]},{"id":"2","children":[]}];
    let b = JSON.stringify(actual) === JSON.stringify(expected);
    if (!b) console.log(JSON.stringify(actual, null, 2))
    else console.log(true);
    }
    {
    let actual = buildTree([{id: "1", "children": []}])
    let expected = [{"id":"1","children":[]}];
    let b = JSON.stringify(actual) === JSON.stringify(expected);
    if (!b) console.log(JSON.stringify(actual, null, 2))
    else console.log(true);
    }

    Try it online!