玖叶教程网

前端编程开发入门

js数组去重到底怎么最快(js怎么对数组去重)

常用数组去重

环境:mac 10.14.3 (18D109),node-8.6,8G内存,测试数据量15W

测试基础

const { log, c } = require('./util')

const origin = Array.from(new Array(100000), (x, index) => {
  return index
})

// 包含数据尽量均匀分布
const target = Array.from(new Array(50000), (x, index) => {
  return index + index
})

const start = Date.now()
log(`${c.cyan}start${c.end}`)

function merge2Array() {
  // 不同实现逻辑
}

log(`${c.cyan}after merge length${c.end}: ${merge2Array4(origin, target).length}`)

const end = Date.now()
log(`${c.red}all times${c.end}: ${end - start}`)

第一种

/**
 * 第一种,看似简洁,性能是不是也很牛逼?
 * filter + indexOf
 * @param {*} origin
 * @param {*} target
 */
function merge2Array(origin, target) {
  const result = origin.concat(target)
  return result.filter((item, index) => {
    return result.indexOf(item) === index
  })
}

第二种

/**
 * 第二种,复杂点(是不是感觉有点像某种排序了?),代码这么多性能是不是很糟?
 * for + for
 * @param {*} origin
 * @param {*} target
 */
function merge2Array1(origin, target) {
  const result = origin.concat(target)
  let len = result.length
  for (let i = 0; i < len; i++) {
    for (let j = i + 1; j < len; j++) {
      if (result[i] === result[j]) {
        result.splice(j, 1);
        // splice 会改变数组长度,所以要将数组长度 len 和下标 j 减一
        len--;
        j--;
      }
    }
  }
  return result
}

第三种

/**
 * for + includes
 * @param {*} origin
 * @param {*} target
 */
function merge2Array2(origin, target) {
  origin = origin.concat(target)
  const result = []
  for (const i of origin) {
    !result.includes(i) && result.push(i)
  }
  return result
}


第四种

/**
 * sort + for
 * @param {*} origin
 * @param {*} target
 */
function merge2Array3(origin, target) {
  origin = origin.concat(target)
  origin.sort()
  const result = [origin[0]]
  const len = origin.length
  for (let i = 1; i < len; i++) {
    if (origin[i] !== origin[i-1]) {
      result.push(origin[i])
    }
  }
  return result
}

第五种

/**
 * Array.from + Set
 * 代码最少,性能最好?
 * @param {*} origin
 * @param {*} target
 */
function merge2Array4 (origin, target) {
  return Array.from(new Set([...origin, ...target]))
}

第六种

/**
 * for + obj-keys
 * 单一基础类型最快的
 * @param {*} origin
 * @param {*} target
 */
function merge2Array5(origin, target) {
  origin = origin.concat(target)
  const result = []
  const tagObj = {}
  for (const i of origin) {
    if (!tagObj[i]) {
      result.push(i)
      tagObj[i] = 1
    }
  }
  return result
}

第七种

/**
 * for + set
 * 多种基础数据类型最快
 * @param {*} origin
 * @param {*} target
 */
function merge2Array6(origin, target) {
  origin = origin.concat(target)
  const result = []
  const set = new Set()
  for (const i of origin) {
    if (!set.has(i)) {
      result.push(i)
      set.add(i)
    }
  }
  return result
}

数据级上升(150W)

我们针对最后两种方法进行数量级提升,提升至150w数据

Array.from + Set

for + obj-keys

for + set

总结

  • 如果你去重的是单一基础类型,那直接用for-obj-keys方式是最快的
  • 如果你去重的是多种基础类型,最快的是for-set方式是最快的


发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言