大家好,这是我在掘金发表的第一篇文章,肯定有不足与错漏之处,还请大家不吝赐教.
事情起因是这样的,在业务中经常碰到两个数组相互比较的情况,这个相信大家应当基本都会使用两重循环去解决,但总感觉这种方式不太优雅,而且性能也不太行,于是经过一番研究对比,才有了这篇文章,以下为代码示例
方式一,使用两层循环比较
/*
需求: 有两个数组,其中一个为对象数组,另一个为数字数组.要求对这两个数组进行比较,
若对象数组中含有数字数组中的数字,则将属性拼接到一个新的数组,示例如下
*/
const arr1 = new Array(10000).fill(undefined).map((it,i) => i) // 长度为10000的数字数组
const arr2 = new Array(10000).fill(undefined).map((it,i) => ({a: i+1000,code: 'code' + i})) // 长度为10000的对象数组
const codes = []
const startTime = new Date().getTime() // 记录开始时间
arr1.forEach((it) => {obj[it] = true})
arr2.forEach((item) => {
if (arr1.includes(item.a)) {
codes.push({ code: item.code })
}
})
const endTime = new Date().getTime() // 记录结束时间
console.log(endTime-startTime)
控制台打印如下
方式二,使用对象映射减少一层循环
const arr1 = new Array(10000).fill(undefined).map((it,i) => i) // 长度为10000的数字数组
const arr2 = new Array(10000).fill(undefined).map((it,i) => ({a: i+1000,code: 'code' + i})) // 长度为10000的对象数组
const codes = []
const startTime = new Date().getTime() // 记录开始时间
let obj = Object.create(null) // 创建一个空对象
arr1.forEach((it) => {obj[it] = true}) // 添加值的映射
arr2.forEach((item) => {
if (obj[item.a]){
codes.push({ code: item.code })
}
})
obj = null // 内存释放
const endTime = new Date().getTime() // 记录结束时间
console.log(endTime-startTime)
控制台打印如下
总结
方式一需要循环的次数更多,在比较的数组长度较大时会有性能问题,比如上面的例子,方式一需要循环10000*10000次,如果循环次数较少,也可以采用.
方式二也需要循环,但使用了一个临时对象来保存条件,总共需要循环10000*2次,长数组比较时能获得较好的性能,但使用了一个临时变量,使用的内存会高于第一种方式