传统2个数组的嵌套查询一般通过两个循环体嵌套实现,时间复杂度为:n^2;
而通过建立索引对象的形式的时间复杂度为:n;这种牺牲内存来达到复杂度降幂的的方法能提高多少性能呢?
下面是以数组1长度为10000;数组2为50000的乱序数组进行测试的测试结果。(测试结果的单位都是ms)
Firefox测试结果: 平均快48倍
// 第一次
传统的嵌套循环:1479
建立索引:30
// 第二次
传统的嵌套循环:1852
建立索引:36
// 第三次
传统的嵌套循环:1754
建立索引:38
Chrome测试结果: 平均快64倍
// 第一次
传统的嵌套循环:1800
建立索引:26
// 第二次
传统的嵌套循环:1297
建立索引:35
// 第三次
传统的嵌套循环:2522
建立索引:27
IE11测试结果:平均快11倍
// 第一次
传统的嵌套循环:110431
建立索引:616
// 第二次
传统的嵌套循环:7172
建立索引:689
// 第三次
传统的嵌套循环:7310
建立索引:686
完整的代码(实际使用中请考虑数据类型校验和是否为空判断)
// 情景:从数组arr1的id拿到数组arr2中的所有记录,统计急了num的总和写回到arr1中
// 模拟2个数组
var start = 1000000
// 定义模拟2个数组的方法;count: arr1的长度值;n: 为arr2为arr1的长度的多少倍
function getArr(count, n) {
var o = {
arr1: [],
arr2: []
}
for(var i = 0; i<count; i++){
o.arr1.push({id: start+i,count: 0})
for(var j = 0; j < n; j++){
o.arr2.push({
id: start + i,
num: Math.round(Math.random()*1000)
})
}
}
// 简单的打乱数组
o.arr2.sort(function (a, b) {
return a.num - b.num
})
return o
}
// 传统方法的嵌套循环
function setArrCount2(o) {
var l1 = o.arr1.length
var l2 = o.arr2.length
var arr1 = o.arr1
var arr2 = o.arr2
for(var i = 0; i < l1; i++) {
for(var j = 0; j < l2; j++) {
if(arr1[i].id === arr2[j].id){
arr1[i].count += arr2[j].num
}
}
}
console.log(arr1)
return arr1
}
// 使用降幂算法
// arr2进行分组,建立以id值为key的对象
function getArrGroup(arr, id) {
var o = {}
var len = arr.length
var index
for(var i = 0; i < len; i++){
index = arr[i][id]
if(o[index]===undefined){
o[index] = [arr[i]]
} else {
o[index].push(arr[i])
}
}
return o
}
// 给arr1项的count赋值
function setArrCount(arr, o, fn) {
var len = arr.length
for(var i = 0; i < len; i++) {
arr[i] = fn(arr, o, i)
}
console.log(arr)
return arr
}
// 统计num的值
function getCount(arr) {
var count = 0
var len = arr.length
for(var i = 0; i < len; i++){
count += arr[i].num
}
return count
}
function someLogic(arr, o, i){
arr[i].count = getCount(o[arr[i].id])
return arr[i]
}
// 拿到2个数组
var myList = getArr(10000,5)
var myList1 = getArr(10000,5)
// 传统方法
var st = new Date().getTime()
setArrCount2(myList1)
console.log(new Date().getTime() - st)
//
var startTime = new Date().getTime()
var obj = getArrGroup(myList.arr2, 'id')
setArrCount(myList.arr1, obj, someLogic)
console.log(new Date().getTime() - startTime)
核心代码:
// 使用降幂算法
// arr2进行分组,建立以id值为key的对象
function getArrGroup(arr, id) {
var o = {}
var len = arr.length
var index
for(var i = 0; i < len; i++){
index = arr[i][id]
// 建立索引,防止覆盖
if(o[index]===undefined){
o[index] = [arr[i]]
} else {
o[index].push(arr[i])
}
}
return o
}
// 给arr1项的count赋值
function setArrCount(arr, o, id, fn) {
var len = arr.length
for(var i = 0; i < len; i++) {
arr[i] = fn(arr, o, i)// fn定义处理逻辑
}
console.log(arr)
return arr
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。