js处理层级数据结构的一些总结

开发者对复杂的数据结构的处理能力也是体现开发者水平的一个度量吧。。。最近发现本身对一些嵌套数据结构、层级数据结构的处理能力不大足。。。常常被这些把本身绕晕。。。严重影响开发效率。。。就稍微低总结了一下下。。。javascript

1、mongodb设计层级关系数据(这里主要说的是mongoose)vue

①假设有这样的一个场景。某个文章下面有评论,每一个评论能够被回复,每一个回复又能够被回复...java

首先,咱们知道,普通的一对多的关系,能够经过引用,populate操做找出相应的引用对象,如:node

var essaySchema = new mongoose.Schema({   //文章schema
    user:{
        type: mongoose.Schema.Types.ObjectId, //发布者的引用
        ref: 'user', //引用自User Model
        require: true //非空
    },
  ...
});

文章与评论的关系,就是一对多。天然也是按照这种处理方式便可。git

可是,评论与回复的关系,就有点意思了。首先,评论和回复,回复与该回复的回复虽然是不一样的东西(看着就拗口),可是这些的shema的信息都是由相同的字段构成。也就是说,能够说是本身嵌套了多个本身。github

这个时候,就要这样处理了:mongodb

//评论Schema定义
var commentSchema = new mongoose.Schema({
    content: {
        type: String, 
        require: true 
    },
    created: {
        type: Date, 
        "default": Date.now 
    },
    user: {
        type: mongoose.Schema.Types.ObjectId, //用户的引用
        ref: 'user', //引用自User Model
        require: true //非空
    },
    subComment: [this], //自评论的类型为评论类型,也就是自己类型
});

最关键就是最后一句,实质上就是递归地引用了自身。查找的时候,也确实是须要根据上一层的subComment找到本身。套了深层的时候,查找的时候会容易绕晕,并且查找速度也会下降。建议作层级限制。express

实践小项目:一个简单版node+express+mongodb的图片分享api

 

2、实际开发场景中的层级关系数据数组

①假设有这样的一个场景,有一个商品数组,每一个商品有两个维度,颜色和规格。颜色和规格的组合会产生的sku(能够理解为每种组合状况的一个标识)数量为颜色数量*规格数量。当咱们渲染完毕以后,顾客每切换一个规格,都要找到相应的sku。

设想一下,假如顾客每切换一个规格,咱们就根据第几个商品,切换的规格,没有被切换的规格去查找。那么每次都是一个三重循环。。。

这种状况下,比较好的作法就是,初始化得到数据的时候,创建三维数据,即Array[商品index][颜色][规格]。这样每次切换,只要读取相应的项就能够找到sku了。

可是,倘若商品的维度不是二维,而是多维呢,并且不必定每种组合都存在这样的商品的呢?

构造数据的方法,就显得不大明智了,一是组合数过多,并非每种组合商品都存在,而是循环太多重。

这个时候,又要利用对象去构造数据了。

第一步,根据展现须要构造。展现的时候,只须要知道,某个商品的某个维度是某个值便可。即:

var obj = {[
{'商品':'1',sku:'','维度1’:'...','维度2':'...',...}
]}

当点击切换维度的时候,首先根据原来的维度信息,更新用户新选的维度。遍历该新的维度对象,与维度信息数据比较,若是一一相符则找到新的sku。而后再更新便可。  

在这里就要明确本身的"筹码"与"目标",根据哪些东西,经过哪些途径能够到达目标。将每一步拆分红一个小方法去作。。。

 

②假设有这样的一个场景,首先要根据一些规则合并一些请求去请求不一样的数据(即返回的数据,是多个参数结合在一块儿的,必须还要解析出数据原先的对应关系),而后得到部分数据。再用得到的部分数据中某条数据的参数去请求第二个接口。而后得到不一样的一些数据。

首先想到的多是用promise处理,待两个接口都请求完毕后再进行处理。可是假如,第一个接口得到的是大部分主要的数据,第二个是小部分的数据。这个时候,等待第二个接口彷佛就有点"不划算"了,特别是在用户体验上,当一个用户打开某个页面的时候,白屏就很差啦。  

这个时候,咱们就要善于利用对象去构造符合咱们的数据对象了。

咱们能够这样初始化一个对象:

var obj = { 
  '惟一的参数1'+‘_’+'惟一的参数1的id' : {
      第一次请求的数据 : [],
      第二次请求的数据 : [], 
    },
 '惟一的参数2'+‘_’+'惟一的参数2的id' : {
      第一次请求的数据 : [],
      第二次请求的数据 : [], 
    },
   ...
}

  总之,就是要找到惟一的东西,来构造对象。而后再根据这个惟一的值把相应的数据填上。好吧,我都说晕了。看个例子:

for(var i = 0;i < data.length; i++){
   for(var j = 0;j < data[i].params.length; j++){
        obj[data[i].groupId + '_' + data[i].params[j].pcId] = {};
   }
}

//请求数据回来后
for(var i = 0;i < data.length; i++){
   for(var j = 0;j < data[i].params.length; j++){
     obj[data[i].groupId + '_' + data[i].params[j].pcId][firstItem] = data[i].params[j].list; 
   }
}

//第二次数据回来后
for(var i = 0;i < data.length; i++){
   for(var j = 0;j < data[i].params.length; j++){
     obj[data[i].groupId + '_' + data[i].params[j].pcId][moreItem] = data[i].params[j].list; 
   }
}

  注意,若是是用vue,由于第二次请求的数据参数来自第一次,因此请二次数据回来以后,须要用全局api,set方法处理才会生效。

  

好吧。。。说了那么多,或许我本身明白本身在说啥。。。手动苦笑。。。 

相关文章
相关标签/搜索