手写代码

65 阅读2分钟

map实现

Array.prototype.myMap = function(callback) {
  const arr = [];
  // 遍历当前数组每个元素,调用callback得到一个结果数据,添加arr
  for(let index = 0; index < this.length; index++) {
    const element = this[index];
    const result = callback(element, index);
    arr.push(result);
  }
  return arr;
}

reduce实现

Array.prototype.myReduce = function(callback, initialValue) {
  // 结果为初始值
  let result = initialValue;
  // 遍历当前数组每个元素,调用callback得到一个累加结果数据
  for(let index = 0; index < this.length; index++) {
    const element = this[index];
    result = callback(result, element, index)
  }
  return result;
}

filter实现

Array.prototype.myFilter = function(callback) {
  // 结果为初始值
  let arr = [];
  // 遍历当前数组每个元素,调用callback得到一个布尔值 如果为true 将当前element添加到arr
  for(let index = 0; index < this.length; index++) {
    const element = this[index];
    let res = callback(element, index);
    if(res) arr.push(element);
  }
  return arr;
}

find实现

Array.prototype.myFind = function(callback) {
  // 遍历当前数组每个元素,调用callback得到一个布尔值 如果为true 将当前element添加到arr
  for(let index = 0; index < this.length; index++) {
    const element = this[index];
    let res = callback(element, index);
    if(res) {
      return element;
    }
  }
  return undefined;
}

findIndex实现

Array.prototype.myFindIndex = function(callback) {
  // 遍历当前数组每个元素,调用callback得到一个布尔值 如果为true 将当前element添加到arr
  for(let index = 0; index < this.length; index++) {
    const element = this[index];
    let res = callback(element, index);
    if(res) {
      return index;
    }
  }
  return -1;
}

every实现

Array.prototype.myEvery = function(callback) {
  // 遍历当前数组每个元素,调用callback得到一个布尔值 一旦false return false
  for(let index = 0; index < this.length; index++) {
    const element = this[index];
    let result = callback(element, index);
    if(!result) {
      return false;
    }
  }
  return true;
}

some实现

Array.prototype.mySome = function(callback) {
  // 遍历当前数组每个元素,调用callback得到一个布尔值 一旦true return true
  for(let index = 0; index < this.length; index++) {
    const element = this[index];
    let result = callback(element, index);
    if(result) {
      return true;
    }
  }
  return false;
}

数组去重

  1. forEach()和indexOf() 本质是双重遍历,效率差些
  2. forEach() + 对象容器(具有属性名唯一的特点) 只需一重遍历,效率高些
  3. ES6的Array.from() + Set 或者 ... + Set
Array.prototype.myUnique1 = function(arr) {
  let newArr = [];
  if(arr.length===0) return;
  arr.forEach((item, index) => {
    if(newArr.indexOf(item) === -1) {
      newArr.push(item);
    }
  });
  return newArr;
}
Array.prototype.myUnique2 = function(arr) {
  let newArr = [];
  const contain = {}; // 属性名是item 属性值是true
  arr.forEach((item, index) => {
    if(!contain.hasOwnProperty(item)) {
      newArr.push(item);
      contain[item] = true;
    }
  });
  return newArr;
}
Array.prototype.myUnique3 = function(arr) {
  return Array.from(new Set(arr));
}
Array.prototype.myUnique3 = function(arr) {
  return [...new Set(arr)];
}

数组扁平化

取出嵌套数组(多维)中的所有元素放到一个新数组(一维)中

  1. 递归 + reduce() + concat()
  2. ... + some() + concat()

数组扁平化并去重 升序排列

  1. ES6中的flat()
let arr = [2,[2,2,1,[4,5]]];
arr = Array.from(new Set(arr.flat(Infinity))).sort((a,b) => a - b); // [1, 2, 4, 5]
  1. 数组直接转字符串
let arr = [2,[2,2,1,[4,5]]];
arr = arr.toString().split(',').map(item => Number(item)).sort((a,b) => a-b); // [1, 2, 2, 2, 4, 5]
  1. ``

求数组交集

双重for循环

let arr1 = [1,2,2,1];
let arr2 = [2,2]; 
// 期望输出[2,2]

let newArr = []
for(let i = 0; i < arr1.length; i++) {
  let item1 = arr1[i];
  for(let j = 0; j < arr2.length; j ++) {
    let item2 = arr2[j];
    if(item1 === item2) {
      newArr.push(item1);
      break;
    }
  }
}

forEach + includes

let arr1 = [1,2,2,1];
let arr2 = [2,2]; 
// 期望输出[2,2]

let newArr = []
arr1.forEach(item => arr2.includes(item) ? newArr.push(item) : null)
console.log(newArr); // [2,2]

如需差集直接取反

对象转数组

// 将下列对象转成如下结构的数组 [222,123,null,null,888,null,null,null,null,null,null,null]
let obj = {
  1: 222,
  2: 123,
  5: 888
}
let arr = new Array(12).fill(null).map((item,i) => {
  return obj[i+1] || null
})
console.log(arr);

冒泡排序

双层for 循环,一层减一次; 里层减外层,变量相交换。

var arr = [5, 6, 1, 8, 2, 4, 9, 7, 3]
for (var j = 0; j < arr.length - 1; j++) {
    for (var i = 0; i < arr.length - 1 - j; i++) {
        // 外循环 循环一次可以少比较一次
        if (arr[i] > arr[i + 1]) {
            var tmp = arr[i]
            arr[i] = arr[i + 1]
            arr[i + 1] = tmp
        }
    }
}
console.log(arr)

实现浅拷贝

  1. ES6
function clone1(target) {
  if(target instanceof Array) {
    // return [...target]
    // return target.slice()
    // return [].concat(target)
    Array.from(target)
  }else if(target !== null && typeof target === 'object') {
    return {...target}
  }else {
    return target
  }
}
  1. for ... in
  function clone2(target) {
    // 被处理的目标是数组/对象
    if (target instanceof Array || (target !== null && typeof target === "object")) {
      const cloneTarget = target instanceof Array ? [] : {};
      for (const key in target) {
        if (target.hasOwnProperty(key)) {
          cloneTarget[key] = target[key];
        }
      }
      return cloneTarget;
    } else {
      return target;
    }
  }

实现深拷贝

  1. 使用JSON会导致函数属性丢失
function deepClone(origin, target) {
  let target = target || {};
  for(let prop in origin) {
    // 不拷贝原型上的属性 使用hasOwnProperty判断
    if(origin.hasOwnProperty(prop)) {
      if(origin[prop] !== 'null' && typeof(origin[prop] == 'object')) {
        target[prop] = Object.prototype.toString.call() == '[object Array]' ? [] : {};
        deepClone(origin[prop], target[prop]);
      }else {
        // 原始值直接复制
        target[prop] = origin[prop];
      }
    }
  }
  return target;
}