js处理大数据数组循环的一些性能优化

栏目: JavaScript · 发布时间: 7年前

内容简介:上一节我写了观察者模式,是一种设计模式。这些设计模式就是一些思路。当然,关于排序,有快速排序法,关于查找有二分查找法等等,这些都为我们提供了一些思路。那么对于避免不了的大数据循环,分类,查找,有什么更加提高性能,或者说是降低内存消耗的方法吗?假设后端返回数据如下:上面的数据假设是全世界5000多个城市的数据,城市可能分为几个级别,省、市、区等等。

前言

上一节我写了观察者模式,是一种设计模式。这些 设计模式 就是一些思路。当然,关于排序,有快速 排序 法,关于查找有二分查找法等等,这些都为我们提供了一些思路。那么对于避免不了的大数据循环,分类,查找,有什么更加提高性能,或者说是降低内存消耗的方法吗?

案例

假设后端返回数据如下:

{
    "code": 0,
    "message": "",
    "data": {
        "list": [{
            "city_level": "CITY_LEVEL_NONE",
            "parent_id": 0,
            "name": "中国未知",
            "id": 156
        }, {
            "city_level": "CITY_LEVEL_NONE",
            "parent_id": 0,
            "name": "台湾省",
            "id": 710000
        }, {
            "city_level": "CITY_LEVEL_NONE",
            "parent_id": 710000,
            "name": "台湾省未知",
            "id": 719900
        }, {
            "city_level": "CITY_LEVEL_NONE",
            "parent_id": 710000,
            "name": "高雄市",
            "id": 710200
        }, {
            "city_level": "CITY_LEVEL_NONE",
            "parent_id": 710000,
            "name": "花莲县",
            "id": 712200
        }, {
            "city_level": "CITY_LEVEL_NONE",
            "parent_id": 710000,
            "name": "嘉义市",
            "id": 710700
        }, {
            "city_level": "CITY_LEVEL_NONE",
            "parent_id": 710000,
            "name": "南投县",
            "id": 711500
        }, {
            "city_level": "CITY_LEVEL_NONE",
            "parent_id": 710000,
            "name": "澎湖县",
            "id": 712300
        }, {
            "city_level": "CITY_LEVEL_NONE",
            "parent_id": 710000,
            "name": "屏东县",
            "id": 712000
        }, {
            "city_level": "CITY_LEVEL_NONE",
            "parent_id": 710000,
            "name": "台北市",
            "id": 710100
        }, {
            "city_level": "CITY_LEVEL_NONE",
            "parent_id": 710000,
            "name": "台东县",
            "id": 712100
        }, {
            "city_level": "CITY_LEVEL_NONE",
            "parent_id": 710000,
            "name": "台南市",
            "id": 710500
        }, {
            "city_level": "CITY_LEVEL_NONE",
            "parent_id": 710000,
            "name": "台中市",
            "id": 710400
        }, {
            "city_level": "CITY_LEVEL_NONE",
            "parent_id": 710000,
            "name": "桃园市",
            "id": 711100
        }, {
            "city_level": "CITY_LEVEL_NONE",
            "parent_id": 710000,
            "name": "新竹市",
            "id": 710600
        }, {
            "city_level": "CITY_LEVEL_NONE",
            "parent_id": 710000,
            "name": "宜兰县",
            "id": 710900
        }, {
            "city_level": "CITY_LEVEL_NONE",
            "parent_id": 710000,
            "name": "云林县",
            "id": 711700
        }, ...........//此处省略上千条
            ]
            }
           }

上面的数据假设是全世界5000多个城市的数据,城市可能分为几个级别,省、市、区等等。

现在要把这些城市数据处理成级联关系的,类似如下:

[{
          label: '一级 1',
          children: [{
            label: '二级 1-1',
            children: [{
              label: '三级 1-1-1'
            }]
          }]
        }, {
          label: '一级 2',
          children: [{
            label: '二级 2-1',
            children: [{
              label: '三级 2-1-1'
            }]
          }, {
            label: '二级 2-2',
            children: [{
              label: '三级 2-2-1'
            }]
          }]
        }]
        }]

一般人的做法如下: 省、市、区三级,做三个循环,每个循环都要过滤一下,父元素ID和子元素parent_id相等的数据,当然也可以递归循环。

代码可能如下:

this.shengData.forEach((item, index) => {
     item.children = _tempShengData.filter(itm => itm.parent_id == item.id)
      item.children.forEach(initem => {
        initem.children = _tempShengData.filter(itm => itm.parent_id == initem.id)
        if (initem.children.length > 0) {
          initem.children.forEach(sunitem => {
            sunitem.children = _tempShengData.filter(stm => stm.parent_id == sunitem.id)
          })
        }
      })
    })

//_tempShengData 是经过处理之后,去除了父级元素是0或者是空的情况的所有元素, this.shengData是后端返回的所有元素

这里最耗费性能的是循环里面还有过滤。这里消耗会很大!

优化方案

数据库查找快速方法可以建索引。那么数组可以建立类似索引的东西吗?根据上面的数组,我们可以得知,一个parent_id可能有多个子元素,我们可以建立类似key和vue形式的对象,通过对象的key,来直接获取vue值,岂不是更快?

这样就循环一次就可以了,将上面代码改进如下:

// 将所有的数据进行一个分类,key是parent_id,value是children

let regionObj = {}
城市数据.forEach(item => {
      regionObj[item['parent_id']] = regionObj[item['parent_id']] || []
       regionObj[item['parent_id']].push(item)
 })

这样regionObj这个对象就是以parent_id为key,value是一个children元素的集合了。

然后再进行一次分类吧

this.shengData.forEach((item, index) => {
        item.children = regionObj[item.id] ? regionObj[item.id] : []
      item.children.forEach(initem => {
        initem.children = regionObj[initem.id] ? regionObj[initem.id] : []
        if (initem.children.length > 0) {
          initem.children.forEach(sunitem => {
            sunitem.children = regionObj[sunitem.id] ? regionObj[sunitem.id] : []
          })
        }
      })
    })

这样比之前快了很多。


以上所述就是小编给大家介绍的《js处理大数据数组循环的一些性能优化》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。

Responsive Web Design

Responsive Web Design

Ethan Marcotte / Happy Cog / 2011-6 / USD 18.00

From mobile browsers to netbooks and tablets, users are visiting your sites from an increasing array of devices and browsers. Are your designs ready? Learn how to think beyond the desktop and craft be......一起来看看 《Responsive Web Design》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具