js处理层级数据结构的方法小结


Posted in Javascript onJanuary 17, 2017

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

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

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

首先,我们知道,普通的一对多的关系,可以通过引用,populate操作找出相应的引用对象,如:

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

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

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

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

//评论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找到自己。套了深层的时候,查找的时候会容易绕晕,而且查找速度也会降低。建议做层级限制。

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

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

①假设有这样的一个场景,有一个商品数组,每个商品有两个维度,颜色和规格。颜色和规格的组合会产生的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方法处理才会生效。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持三水点靠木!

Javascript 相关文章推荐
Prototype使用指南之dom.js
Jan 10 Javascript
js+FSO遍历文件夹下文件并显示
Mar 07 Javascript
40个新鲜出炉的jQuery 插件和免费教程[上]
Jul 24 Javascript
jQuery基本选择器(实例及表单域value的获取方法)
May 20 Javascript
JS获取和修改元素样式的实例代码
Aug 06 Javascript
node.js + socket.io 实现点对点随机匹配聊天
Jun 30 Javascript
详解如何使用koa实现socket.io官网的例子
Nov 04 Javascript
JS实现动态添加外部js、css到head标签的方法
Jun 05 Javascript
解决VUE-Router 同一页面第二次进入不刷新的问题
Jul 22 Javascript
js实现淘宝浏览商品放大镜功能
Oct 28 Javascript
快速解决vue2+vue-cli3项目ie兼容的问题
Nov 17 Vue.js
vue实现树状表格效果
Dec 29 Vue.js
JS中Select下拉列表类(支持输入模糊查询)功能
Jan 17 #Javascript
JavaScript的事件机制详解
Jan 17 #Javascript
js判断手机号是否正确并返回的实现代码
Jan 17 #Javascript
深入理解javascript中的 “this”
Jan 17 #Javascript
JavaScript正则表达式exec/g实现多次循环用法示例
Jan 17 #Javascript
Javascript设计模式之装饰者模式详解篇
Jan 17 #Javascript
微信小程序图表插件(wx-charts)实例代码
Jan 17 #Javascript
You might like
php新浪微博登录接口用法实例
2014/12/23 PHP
PHP类的声明与实例化及构造方法与析构方法详解
2016/01/26 PHP
解析jQuery与其它js(Prototype)库兼容共存
2013/07/04 Javascript
JS.elementGetStyle(element, style)应用示例
2013/09/24 Javascript
jQuery.event兼容各浏览器的event详细解析
2013/12/18 Javascript
jquery用data方法获取某个元素上的事件
2014/06/23 Javascript
Node.js安装教程和NPM包管理器使用详解
2014/08/16 Javascript
jQuery实现不断闪烁文字的方法
2015/05/15 Javascript
JavaScript中的parse()方法使用简介
2015/06/12 Javascript
js正则表达式验证邮件地址
2015/11/12 Javascript
JavaScript结合Bootstrap仿微信后台多图文界面管理
2016/07/22 Javascript
javascript简单实现等比例缩小图片的方法
2016/07/27 Javascript
jQuery中on方法使用注意事项详解
2017/02/15 Javascript
详细AngularJs4的图片剪裁组件的实例
2017/07/12 Javascript
jQuery中each遍历的三种方法实例分析
2018/09/07 jQuery
Vue通过ref父子组件拿值方法
2018/09/12 Javascript
解决vue动态为数据添加新属性遇到的问题
2018/09/18 Javascript
vue项目前端错误收集之sentry教程详解
2019/05/27 Javascript
JS函数进阶之prototy用法实例分析
2020/01/15 Javascript
详解Django中的form库的使用
2015/07/18 Python
简单谈谈Python中的几种常见的数据类型
2017/02/10 Python
Python Grid使用和布局详解
2018/06/30 Python
pandas每次多Sheet写入文件的方法
2018/12/10 Python
使用python将最新的测试报告以附件的形式发到指定邮箱
2019/09/20 Python
python面向对象之类属性和类方法案例分析
2019/12/30 Python
tensorflow实现测试时读取任意指定的check point的网络参数
2020/01/21 Python
new_zeros() pytorch版本的转换方式
2020/02/18 Python
基于Python数据结构之递归与回溯搜索
2020/02/26 Python
StubHub新加坡:购买和出售全球活动门票
2017/03/10 全球购物
个人求职简历中英文自我评价
2013/12/16 职场文书
庆七一活动总结
2014/08/27 职场文书
部队2014年终工作总结
2014/11/27 职场文书
2015年高中语文教学总结
2015/08/18 职场文书
Python离线安装openpyxl模块的步骤
2021/03/30 Python
pytorch Dropout过拟合的操作
2021/05/27 Python
刚学完怎么用Python实现定时任务,转头就跑去撩妹!
2021/06/05 Python