从数组构造树

时间:2014-04-12 08:16:30

标签: javascript mongodb

我是一个初学者,提示算法,用于从表单数组构建树:

var data = [
   {id: 1,level:1,left_key:1,right_key:12, caption: "Books"},
   {id: 2,level:2,left_key:2,right_key:11, caption: "Programming"},
   {id: 3,level:3,left_key:3,right_key:4, caption: "Languages"},
   {id: 4,level:3,left_key:5,right_key:10, caption: "Databases"},
   {id: 5,level:4,left_key:6,right_key:7, caption: "MongoDB"},
   {id: 6,level:4,left_key:8,right_key:9, caption: "dbm"}
];

数据格式取自link。 从Mongodb数据库请求的这种格式的数据构建树种:

<ol>      
   <li>
       <span> Books </span>
       <ol>
           <li>
              <span> Programming </span>
           </li>
       </ol>
   </li>
</ol>

我无法理解树遍历的原理。 附:我想没有第三方库

2 个答案:

答案 0 :(得分:0)

我想你需要这样的东西

function make_tree() {    
  var tree = document.getElementById("tree");
  data.forEach(function(elem){
    var elem_parent = document.getElementById("tree_" + elem.level);    
    if(elem_parent){      
      var cur_element = document.createElement("li");
      cur_element.setAttribute('id','tree_' + elem.level + "_" + elem.id);
      cur_element.innerHTML = "<span>" + elem.caption + "</span>";
      elem_parent.appendChild(cur_element);
    }
    else {      
      var cur_parent = document.createElement("ol");
      cur_parent.setAttribute('id','tree_' + elem.level);      
      var cur_element = document.createElement("li");
      cur_element.setAttribute('id','tree_' + elem.level + "_" + elem.id);
      cur_element.innerHTML = "<span>" + elem.caption + "</span>";
      cur_parent.appendChild(cur_element);
      parent_before = document.getElementById("tree_" + (elem.level - 1)); 
      if (parent_before) parent_before.appendChild(cur_parent);
      else tree.appendChild(cur_parent);
    }
  });
}

<强> EXAMPLE FIDDLE

答案 1 :(得分:0)

更好的答案是简单地将树结构存储在MongoDB文档中:

{
    "0": {
        "caption": "Books",
        "items": {
            "0": {
                "caption": "Programming",
                "items": {
                    "0": {
                        "caption": "Languages",
                    },
                    "1": {
                        "caption": "Databases",
                        "items": {
                            "0": {
                                "caption": "MongoDB"
                             },
                             "1": {
                                 "caption": "dbm"
                             }
                        }
                    }
                }
            }
        }
    }
} 

它有一个自然的顺序,并提供一个非常简单的方法来获得一个可以在构建菜单的概念中遍历的结构。

更新也非常简单,所以要添加一个新项目,比如说语言&#34;语言&#34;等级,然后你有一个明确的更新路径:

 db.collection.update(
     {},
     {
       "$set": { 
           "0.items.0.items.0.items.0.caption": "C++"
       }
     }
)

并添加另一个:

 db.collection.update(
     {},
     {
       "$set": { 
           "0.items.0.items.0.items.1.caption": "Pascal"
       }
     }
)

现在,与所有树结构一样,确实需要了解您要插入的级别。这里的设计(以及可怕的过度设计)至少允许轻松更新。这是一个众所周知的查询结构,但这不是重点。

但当然这里的限制是针对&#34;小&#34;树结构(仍然在16MB以下和相当多的树),但对于任何特别大的东西,大型模型实现的地方

在样本数据中以处理方式处理树的事情是每个节点需要在时间中拉入一个节点。正如文档中所述,您正在提取这样的结果:

var databaseCategory = db.categories.findOne( { _id: "Databases" } );
db.categories.find({ 
    left: { $gt: databaseCategory.left }, 
    right: { $lt: databaseCategory.right } 
});

所以有一种方法可以将所有孩子从给定节点中拉出来,但现在考虑一下为了添加任何新项目你需要做什么:

因此,为了像之前所做的那样在语言节点中添加内容,不仅要处理插入新值,还要更新树中的所有其他节点值以表示位置,如示例文档中所示

有很多方法可以通过&#34; bucketing&#34;节点上的值,以便允许插入和删除,但就像这样建模树结构的整个主题,在这个网站上的答案范围之外。

因此,对于您生成菜单的特定用例,最好使用存储的本机数据结构功能,只需使用本机结构存储和调用数据即可使用它。