像这种数组:
let jsonArray = [{id: "1", name: "张三"}, {id: "2", name: "赵四"}, {id: "3", name: "王五"}]
数组元素不是直接在第一层的,数据量大的时候逻辑怎么写才使得性能比较好呢,就是比较快处理完?下面介绍几种方法,有测试数据对比:
一般来说,要将这种数组去重,得到新数组,第一个想法就是遍历,一般写法需要两个遍历:
【方法一】:
let jsonArray = [{id: "1", name: "张三"}, {id: "2", name: "赵四"}, {id: "3", name: "王五"}, {id: "3", name: "王五"}]
let resultArray = []
jsonArray.forEach( ( item ) => {
let flag = false
for( let i=0; i<resultArray.length; i++ ) {
if ( item.id === resultArray[i].id ) {
flag = true
break
}
}
if ( !flag ) {
resultArray.push( item )
}
})
console.log( resultArray )//去重完成
一般都是这个做法吧,这里使用for循环break也算是优化了一点性能了,但是大数据量的情况,因为resultArray是不断增长的,随着数据量级越来越大,这里的遍历就会越来越吃力,越到后面越慢;
能不能用一个遍历就搞定它?答案肯定是可以的
在不改变原数组的前提下,一个for循环去重的做法:
【方法二】:
let jsonArray = [{id: "1", name: "张三"}, {id: "2", name: "赵四"}, {id: "3", name: "王五"}, {id: "3", name: "王五"}]
let resultArray = [], itemIds = []
jsonArray.forEach( ( item ) => {
if ( itemIds.indexOf(item.id) <0 ) {
itemIds.push(item.id)
resultArray.push( item )
}
})
itemIds = []
console.log( resultArray )//去重完成
【方法三】,也是最快的一种:
let jsonArray = [{id: "1", name: "张三"}, {id: "2", name: "赵四"}, {id: "3", name: "王五"}, {id: "3", name: "王五"}]
let resultArray = [], itemIds = {}
jsonArray.forEach( ( item ) => {
if ( !itemIds[item.id] ) {
itemIds[item.id] = true
resultArray.push( item )
}
})
itemIds = {}
console.log( resultArray )//去重完成
第二、第三种做法是不是感觉会快很多?因为去掉了一个for循环,肯定是快很多的,牺牲一点点内存(多声明一个存储变量itemIds)就可以将性能发挥到极致,上面的方法二,itemIds用数组+indexOf(),性能处于中等位置,但也都比两个for循环要好的,键值对的方法最快,毕竟键值对查找几乎不用时间,不受下标影响;
下面我们用【例子】事实说话:
同样是10万条数据,同样混入10条重复数据,三种方法得出的结果令人大吃一惊:
方法一,时间为 9915ms:
方法二,时间为 5480ms:
方法三,时间为 7ms !!!:
我把测试代码放在下面,可以自己拷贝去浏览器控制台打印对比一下:
let jsonArray = []
for(let i=0;i<100000;i++){jsonArray.push({id:i, name: '名'+i })}
jsonArray.push({id:10, name: '重复' })
jsonArray.push({id:100, name: '重复' })
jsonArray.push({id:1000, name: '重复' })
jsonArray.push({id:10000, name: '重复' })
jsonArray.push({id:20000, name: '重复' })
jsonArray.push({id:30000, name: '重复' })
jsonArray.push({id:40000, name: '重复' })
jsonArray.push({id:50000, name: '重复' })
jsonArray.push({id:60000, name: '重复' })
jsonArray.push({id:70000, name: '重复' })
let resultArray = []
console.time()
jsonArray.forEach( ( item ) => {
let flag = false
for( let i=0; i<resultArray.length; i++ ) {
if ( item.id === resultArray[i].id ) {
flag = true
break
}
}
if ( !flag ) {
resultArray.push( item )
}
})
console.timeEnd()
console.log(resultArray)
let jsonArray = []
for(let i=0;i<100000;i++){jsonArray.push({id:i, name: '名'+i })}
jsonArray.push({id:10, name: '重复' })
jsonArray.push({id:100, name: '重复' })
jsonArray.push({id:1000, name: '重复' })
jsonArray.push({id:10000, name: '重复' })
jsonArray.push({id:20000, name: '重复' })
jsonArray.push({id:30000, name: '重复' })
jsonArray.push({id:40000, name: '重复' })
jsonArray.push({id:50000, name: '重复' })
jsonArray.push({id:60000, name: '重复' })
jsonArray.push({id:70000, name: '重复' })
let resultArray = [], itemIds = []
console.time()
jsonArray.forEach( ( item ) => {
if ( itemIds.indexOf(item.id) < 0 ) {
itemIds.push(item.id)
resultArray.push( item )
}
})
itemIds = []
console.timeEnd()
console.log(resultArray)
let jsonArray = []
for(let i=0;i<100000;i++){jsonArray.push({id:i, name: '名'+i })}
jsonArray.push({id:10, name: '重复' })
jsonArray.push({id:100, name: '重复' })
jsonArray.push({id:1000, name: '重复' })
jsonArray.push({id:10000, name: '重复' })
jsonArray.push({id:20000, name: '重复' })
jsonArray.push({id:30000, name: '重复' })
jsonArray.push({id:40000, name: '重复' })
jsonArray.push({id:50000, name: '重复' })
jsonArray.push({id:60000, name: '重复' })
jsonArray.push({id:70000, name: '重复' })
let resultArray = [], itemIds = {}
console.time()
jsonArray.forEach( ( item ) => {
if ( !itemIds[item.id] ) {
itemIds[item.id] = true
resultArray.push( item )
}
})
itemIds = {}
console.timeEnd()
console.log(resultArray)