JavaScript数组知识及面试题

266 阅读2分钟

一、数组扁平化

1、ES6的flat

// arr.flat([depth])
// depth表示展开深度,默认为1,这里直接传入Infinity(无限大,所以不论多少层都可以展开)。
const array = [1, 2, [3, 4, [5, [6]]]]
const result = array.flat(Infinity)  // [1, 2, 3, 4, 5, 6]

// [实现flat] concat+递归
function myFlat(arr) {
  let result = [];
  arr.forEach(item => {
    if (Array.isArray(item)) {
      // 使用concat
      result = result.concat(arguments.callee(item));
      // 使用扩展运算符...
      // result.push(...arguments.callee(item));
    } else {
      result.push(item);
    }
  })
  return result;
}

2、递归调用

const testArray = [1, [2, [3, [4, [5, [6, [7, [[[[[[8, ['ha']]]]]]]]]]]]]];
function flatten(arr) {
  let result = [];
  arr.forEach((item)=>{
    if (Array.isArray(item)) {
      // 是数组的话,递归调用
      result = result.concat(flatten(item));
    } else {
      // 不是数组的话push
      result.push(item);
    }
  })
  return result; 
}

const result = flatten(testArray);
console.log(result); // [ 1, 2, 3, 4, 5, 6, 7, 8, 'ha'] 

3、reduce

const testArray = [1, [2, [3, [4, [5, [6, [7, [[[[[[8, ['ha']]]]]]]]]]]]]];
function flatten(arr) {
  return arr.reduce((prev, curv) => {
    return prev.concat(Array.isArray(curv) ? flatten(curv) : curv);
  }, []);
}
const result = flatten(testArray);
console.log(result); // [ 1, 2, 3, 4, 5, 6, 7, 8, 'ha'] 

4、扩展运算符实现

function flatten(arr) {
  while (arr.some(item => (Array.isArray(item)))) {
    arr = [].concat(...arr);
  }
  return arr;
}
const result = flatten(testArray);
console.log(result); // [ 1, 2, 3, 4, 5, 6, 7, 8, 'ha']

二、数组去重

1、Set

var arr = [1,2,2,3,4,4,4,5,5,6,'a', 'a', 'b', true, true, false]
var setArr = new Set(arr); // 利用Set去重
var result = [...setArr]; // 把set结构的类数组转为普通数组
// result输出结果:[1, 2, 3, 4, 5, 6, 'a', 'b', true, false]

2、循环遍历+includes去重

function delRepeat(arr) {
  var result = [];
  arr.forEach(function(item) {
    !result.includes(item) && result.push(item)
  })
  return result;
}
var arr = [1,2,2,3,4,4,4,5,5,6,'a', 'a', 'b', true, true, false];
delRepeat(arr)
// 输出结果:[1, 2, 3, 4, 5, 6, 'a', 'b', true, false]

3、利用对象key去重

function delRepeat(arr) {
  var obj = {};
  arr.forEach(function(item) {
    obj[item] = item;
  })
  return Object.values(obj);
}
var arr = [1,2,2,3,4,4,4,5,5,6,'a', 'a', 'b', true, true, false];
delRepeat(arr)
// 输出结果:[1, 2, 3, 4, 5, 6, 'a', 'b', true, false]

三、伪数组

伪数组是一个含有length属性、按索引方式存储数据的对象

如: arrayLike = {0: 'a', 1: 'b', length: 2} 常见的伪数组:arguments、NodeList

【伪数组如何转化为数组】

1、Array.from()

Array.from({0: 'a', 1: 'b', length: 2}) // ['a', 'b']

2、通过 call/apply 改变 this 或者 arguments 来完成转化

最常见的转换是 Array.prototype.slice

const arrayLike = {
  0: 3,
  1: 4,
  2: 5,
  length: 3
}
Array.prototype.slice.call(arrayLike) // [3, 4, 5]
Array.apply(null, arrayLike) // [3, 4, 5]
Array.prototype.concat.apply([], arrayLike) // [3, 4, 5]