数组去重、数组扁平化

139 阅读1分钟

一、去重

1. ES5

1.1 排序

const unique = function(nums) {
  const res = [];
  let len = nums.length;
  nums.sort((a, b) => a - b);
  for (let i = 0; i < len - 1; i++) {
    if (nums[i] == nums[i + 1]) continue;  // 注意
    res.push(nums[i]);
  }
  if (nums[len - 1] !== res[res.length - 1]) res.push(nums[len - 1]);
  return res;
}

时间复杂度:O(n)。

1.2 indexOf

const unique = function(nums) {
  const res = [];
  for (let i = 0; i < nums.length; i++) {
    if (res.indexOf(nums[i]) === -1) {
      res.push(nums[i]);
    }
  }
  return res;
}

2. ES6

ES6含义是ES5.1版以后的JavaScript的下一代标准,涵盖了ES2015、ES2016、ES2017等。

2.1 Set 数据结构

Set内部判断相等使用的是类似严格相等的运算,唯一区别在于Set认为 NaN和自身相等。

另外,两个对象也总是不相等的,因为它们的比较是引用的比较。

// 去除数组的重复成员
[...new Set(array)]
// 去除字符串里面的重复字符
[...new Set('abbacc')].join('')

2.2 Map 数据结构

由于Map中不会出现相同的key值,我们将数组的每个元素作为key存放在Map中。

2.3 includes

const unique = function(nums) {
  let res = [];
  for (let i = 0; i < nums.length; i++) {
    if (res.includes(nums[i])) continue;
    res.push(nums[i]);
  }
  return res;
}

3. 兼容性和场景考虑(NaN?undefined?)

-「NaN」

ES6的Setincludes都认为NaN和自身相等

indexOf认为NaN和自身不相等。相等运算符'=='和严格相等运算符'==='也都认为NaN和自身不相等

-「undefined」

另外,以上所有去重方式都认为undefined和自身相等

二、数组扁平化

将多维数组转为一维数组。

1. flat

手写flat源码

2. 扩展运算符:some

const flatten = (arr) => {
  // 只要有一个成员是数组,那就返回true
  while(arr.some(item => Array.isArray(item))){
      arr=[].concat(...arr);
  }
  return arr;
}

3. toString + split

function flatten(a) {
  let s = a.toString();  // '1, 2, 3'
  let arr = s.split('');  // ['1', '2', '3']
  for (let i = 0; i < arr.length; i++) {
    arr[i] = Number(arr[i]);
  }
  return arr;
}

4. 递归:forEach

function flatten(arr) {
  let result = [];
  arr.forEach((item)=>{
    if (Array.isArray(item)) {
      result = result.concat(flatten(item));
    } else {
      result.push(item);
    }
  })
  return result; 
}