JavaScript:解决算法问题

时间:2019-03-09 17:20:30

标签: javascript

今天我正在研究一个问题,其内容如下:

问题:

  • 输入[{..}, {..}, ..]对象数组;
  • 每个对象都有{"id": required, "children": []}
  • 对象基于"id" and "children"道具具有父子关系
  • 输出[{..}, {..}, ..]树(层次结构)中的数组:多级


输入:

[{
    "id": 1,
    "name": "Earth",
    "children": [2, 3]
}, {
    "id": 2,
    "name": "Asia",
    "children": []
}, {
    "id": 3,
    "name": "Europe",
    "children": [4]
}, {
    "id": 4,
    "name": "Germany",
    "children": [5]
}, {
    "id": 5,
    "name": "Hamburg",
    "children": []
}]

OutPut

[{
    "id": 1,
    "name": "Earth",
    "children": [{
        "id": 2,
        "name": "Asia",
        "children": []
    }, {
        "id": 3,
        "name": "Europe",
        "children": [{
            "id": 4,
            "name": "Germany",
            "children": [{
                "id": 5,
                "name": "Hamburg",
                "children": []
            }]
        }]
    }]
}]

我的方法

我决定通过遍历数组中的每个元素并 递归 查找对象并将对象附加到 children 来解决此问题每个元素。

  

因此,从一开始,我决定仅将一级孩子附加到其各自的父母之后。我的代码如下。

var posts = [{"id":1,"name":"Earth","children":[2,3]},{"id":2,"name":"Asia","children":[]},{"id":3,"name":"Europe","children":[4]},{"id":4,"name":"Germany","children":[5]},{"id":5,"name":"Hamburg","children":[]}]

function getElementById (id, posts) {
	for(var i =0; i< posts.length; i++){
		if(posts[i].id === id){
			var found = posts[i];
///// FUN here -> ////	posts.splice(i, 1);
			return found;
		}
	}
} 

function refactorChildren(element, posts) {
  if(!element.children || element.children.length === 0) {
    return element;
  }
  
  var children = [];
  for(var i = 0; i < element.children.length; i++){
    var childElement = getElementById(element.children[i], posts);    
    children.push(childElement);
  }
  element.children = children;
  
  return element;
}

function iterate(posts) {
  var newPosts = [];
  var des = [...posts]
  for(var i = 0; i < des.length; i++){
    var childedElement = refactorChildren(des[i], des);
     newPosts.push(childedElement);
  }
  
  return newPosts;
}


var filtered = iterate(posts);
console.log(JSON.stringify(filtered))

  

令人惊讶的是上面的代码解决了实际问题(除了少量的工作)

我的预期结果应为以下:仅具有一级子级

的对象数组
[{
    "id": 1,
    "name": "Earth",
    "children": [{
        "id": 2,
        "name": "Asia",
        "children": []
    }, {
        "id": 3,
        "name": "Europe",
        "children": [4]
    }]
}, {
    "id": 4,
    "name": "Germany",
    "children": [{
        "id": 5,
        "name": "Hamburg",
        "children": []
    }]
}]

如果我取消注释///// FUN here -> ////行,我的确会得到上述结果。可以随时随地擦除迭代对象。

所以我的问题是

我想知道-如何识别??所有对象都通过该代码正确地附加到了各自的父对象上吗?我的下一步是向函数refactorChildren(with-childElement)添加递归调用。

AND

仅通过添加posts.splice(i, 1);怎么会从代码中得到我的预期结果?

请帮助我理解,我只是不知道“ HOW”就不能继续前进。

谢谢

2 个答案:

答案 0 :(得分:1)

遍历对象时,您递归调用所有函数,然后从数组中删除对象:

 [
   { id: 1, children: [2], }, // < iterator
   { id: 2, children: [] }, // < gets spliced out recursively
 ]

但是,如果子对象位于其父对象之前的数组中,则将无法正常工作,因为在访问父对象之前将子对象复制到另一个数组中。

答案 1 :(得分:1)

也许您对另一种方法感兴趣,只需要一个循环即可获取父元素及其子元素。

这也适用于未排序的数据。

var data = [{ id: 1, name: "Earth", children: [2, 3] }, { id: 2, name: "Asia", children: [] }, { id: 3, name: "Europe", children: [4] }, { id: 4, name: "Germany", children: [5] }, { id: 5, name: "Hamburg", children: [] }],
    tree = function (array) {
        var r = {},
            children = new Set,
            result = [];

        array.forEach(o => {
            Object.assign(
                r[o.id] = r[o.id] || {},
                o,
                { children: o.children.map(id => (children.add(id), r[id] = r[id] || {})) }
            );
        });
        return Object.values(r).filter(({ id }) => !children.has(id));
    }(data);

console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }