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 相关文章推荐
javascript 清空form表单中某种元素的值
Dec 26 Javascript
js仿百度有啊通栏展示效果实现代码
May 28 Javascript
JavaScript实现select添加option
Jul 03 Javascript
JS脚本实现动态给标签控件添加事件的方法
Jun 02 Javascript
jQuery中实现prop()函数控制多选框(全选,反选)
Aug 19 Javascript
基于dataset的使用和图片延时加载的实现方法
Dec 11 Javascript
vue组件实践之可搜索下拉框功能
Nov 25 Javascript
ES6中Set和Map数据结构,Map与其它数据结构互相转换操作实例详解
Feb 28 Javascript
Vue实现类似Spring官网图片滑动效果方法
Mar 01 Javascript
layui表格分页 记录勾选的实例
Sep 02 Javascript
基于Vue的商品主图放大镜方案详解
Sep 19 Javascript
JavaScript 定时器详情
Nov 11 Javascript
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中$_SERVER的详细参数与说明
2008/07/29 PHP
PHP 配置open_basedir 让各虚拟站点独立运行
2009/11/12 PHP
PHP中is_file不能替代file_exists的理由
2014/03/04 PHP
Yii视图CGridView实现操作按钮定义地址示例
2016/07/14 PHP
Yii2框架RESTful API 格式化响应,授权认证和速率限制三部分详解
2016/11/10 PHP
window.name代替cookie的实现代码
2010/11/28 Javascript
jQuery源码分析-03构造jQuery对象-源码结构和核心函数
2011/11/14 Javascript
jQuery实现点击文本框弹出热门标签的提示效果
2013/11/17 Javascript
jQuery浏览器CSS3特写兼容实例
2015/01/19 Javascript
JS自动倒计时30秒后按钮才可用(两种场景)
2015/08/31 Javascript
详解Javacript和AngularJS中的Promises
2016/02/09 Javascript
layui获取选中行数据的实例讲解
2018/08/19 Javascript
解决VUE中document.body.scrollTop为0的问题
2018/09/15 Javascript
vue src动态加载请求获取图片的方法
2018/10/17 Javascript
layui中的switch开关实现方法
2019/09/03 Javascript
Vue如何基于es6导入外部js文件
2020/05/15 Javascript
python实现的简单猜数字游戏
2015/04/04 Python
python3序列化与反序列化用法实例
2015/05/26 Python
巧用python和libnmapd,提取Nmap扫描结果
2016/08/23 Python
基于python脚本实现软件的注册功能(机器码+注册码机制)
2016/10/09 Python
Pandas中resample方法详解
2019/07/02 Python
如何实现更换Jupyter Notebook内核Python版本
2020/05/18 Python
Windows下Sqlmap环境安装教程详解
2020/08/04 Python
详解Django中views数据查询使用locals()函数进行优化
2020/08/24 Python
python获取linux系统信息的三种方法
2020/10/14 Python
俄语地区最大的中国商品在线购物网站之一:Umka Mall
2019/11/03 全球购物
办公室内勤岗位职责范本
2013/12/09 职场文书
法人代表身份证明书及授权委托书
2014/09/16 职场文书
先进教师个人事迹材料
2014/12/15 职场文书
歼十出击观后感
2015/06/11 职场文书
小学语文教师研修日志
2015/11/13 职场文书
2016年社区中秋节活动总结
2016/04/05 职场文书
员工试用期工作总结
2019/06/20 职场文书
Python中使用ipython的详细教程
2021/06/22 Python
浅谈Redis位图(Bitmap)及Redis二进制中的问题
2021/07/15 Redis
nginx日志格式分析和修改
2022/04/28 Servers