数组相关方法实现

1 实现forEach方法

        Array.prototype.myForEach = function (callback,context=window) {
            let self = this,
                i = 0,
                len = self.length;
            len = self.length;
            for (; i < len; i++) {
                typeof callback == 'function' &&  callback.call(context,self[i], i)
            }
        }

2 实现filter方法

Array.prototype.myFilter = function (callback, context = window) {
            let len = this.length;
            let newArr = [];
            let i = 0;
            for (; i < len; i++) {
                if(callback.apply(context, [this[i], i , this])){
                    newArr.push(this[i]);
                }
            
            }
            return newArr;
        }

3 实现find方法

  • Array.prototype.find() 是一个用于查找数组中符合条件的第一个元素的方法。该方法接受一个回调函数作为参数,该回调函数用于对数组中的每个元素进行测试。该方法返回一个符合测试条件的第一个元素,如果没有符合条件的元素,则返回 undefined。
 var users = [{
                id: 1,
                name: '张三'
            },
            {
                id: 2,
                name: '张三'
            },
            {
                id: 3,
                name: '张三'
            },
            {
                id: 4,
                name: '张三'
            }
        ]
        Array.prototype.myFind = function (callback) {
            for (var i = 0; i < this.length; i++) {
                if (callback(this[i], i)) {
                    return this[i]
                }
            }
        }
        var ret = users.myFind(function (item, index) {
            return item.id === 2
        })

        console.log(ret)

4 实现findIndex方法

Array.prototype.findIndex() 方法在数组中查找并返回第一个满足条件的元素的索引。如果没有找到这样的元素,则返回 -1。该方法接受一个回调函数作为参数,该回调函数接受三个参数:当前元素、当前索引和数组本身。回调函数必须返回一个布尔值,以指示当前元素是否满足条件

 Array.prototype.myFindIndex = function (callback) {
            for (let i = 0; i < this.length; i++) {
                if (callback(this[i], i, this)) {
                    return i;
                }
            }
            return -1;
        }

5 实现map方法

Array.prototype.map() 方法将原数组中的每个元素映射到一个新数组中,并返回新数组。它接受一个回调函数作为参数,该回调函数接受三个参数:当前元素、当前索引和数组本身。回调函数必须返回一个新的值,以指示当前元素在新数组中应该被映射成什么值。

 Array.prototype.myMap = function (callback) {
            const newArray = [];
            for (let i = 0; i < this.length; i++) {
                newArray.push(callback(this[i], i, this))
            }
            return newArray;
        }

6 实现reduce方法

Array.prototype.reduce() 方法对数组中的所有元素执行一个 reducer 函数,并返回单个值。reducer 函数接收 4 个参数:累加器(accumulator)、当前值(currentValue)、当前索引(currentIndex)和数组(array)。累加器用于累计上一次调用 reducer 函数的结果,并将其返回作为下一次调用的累加器。

 Array.prototype.myReduce = function (callback, initialValue) {
            // 首先检查是否提供了初始值
            let accumulator = initialValue !== undefined ? initialValue : this[0];
            for (let i = initialValue !== undefined ? 0 : 1; i < this.length; i++) {
                accumulator = callback(accumulator, this[i], i, this);
            }
            return accumulator;
        }

7 实现every方法

every 方法用于判断数组中的所有元素是否都符合指定的条件。如果所有元素都符合条件,则返回 true,否则返回 false

 Array.prototype.myEvery = function (callback) {
            for (let i = 0; i < this.length; i++) {
                if (!callback(this[i], i, this)) {
                    return false;
                }
            }
            return true;
        }

8 实现some方法

some 方法用于判断数组中是否存在符合指定条件的元素。如果存在,则返回 true,否则返回 false

  Array.prototype.mySome = function (callback) {
            for (let i = 0; i < this.length; i++) {
                if (callback(this[i], i, this)) {
                    return true;
                }
            }
            return false;
        };

9 实现数组扁平化flat方法

flat 方法用于将多维数组扁平化为一维数组。如果需要扁平化的数组中存在多层嵌套的数组,flat 方法会递归地将其展开,直到所有元素都为基本类型为止。

Array.prototype.myFlat = function(depth = 1) {
  if (depth === 0) {
    return this;
  }
  return this.reduce((acc, cur) => {
    if (Array.isArray(cur)) {
      return acc.concat(cur.myFlat(depth - 1));
    } else {
      return acc.concat(cur);
    }
  }, []);
};

const arr = [1, [2, [3, 4], 5], 6];
console.log(arr.myFlat()); // [1, 2, [3, 4], 5, 6]
console.log(arr.myFlat(2)); // [1, 2, 3, 4, 5, 6]

let ary = [1, [2, [3, [4, 5]]], 6];
let str = JSON.stringify(ary);
ary = str.replace(/(\[|\])/g, '').split(',');
str = str.replace(/(\[\]))/g, '');
str = '[' + str + ']';
ary = JSON.parse(str);
let result = [];
let fn = function(ary) {
  for(let i = 0; i < ary.length; i++) }{
    let item = ary[i];
    if (Array.isArray(ary[i])){
      fn(item);
    } else {
      result.push(item);
    }
  }
}

10.实现Array.isArray方法

Array.isArray() 方法用于确定传递的值是否是一个数组,它返回一个布尔值

function myIsArray(value) {
            return Object.prototype.toString.call(value) === "[object Array]";
        }

11.实现Array.of方法

Array.of()方法用于将一组值,转换为数组

  • 这个方法的主要目的,是弥补数组构造函数Array()的不足。因为参数个数的不同,会导致Array()的行为有差异。
  • Array.of()基本上可以用来替代Array()new Array(),并且不存在由于参数不同而导致的重载。它的行为非常统一
function myArrayof() {
  return Array.prototype.slice.call(arguments);
}

这个实现基于一个事实:当 slice() 方法的参数为空时,它会返回一个新数组,其中包含原数组的所有元素。

因此,我们可以使用该方法来实现 Array.of() 方法,只需要将 arguments 对象转换为数组,并返回该数组即可

12 数组去重方法汇总

1. 双层 for 循环

function distinct(arr) {
            for (let i = 0, len = arr.length; i < len; i++) {
                for (let j = i + 1; j < len; j++) {
                    if (arr[i] == arr[j]) {
                        arr.splice(j, 1);
                         // splice 会改变数组长度,所以要将数组长度 len 和下标 j 减一
                         len--;
                         j--;
                    }
                }
            }
           return arr;

        }

思想: 双重 for 循环是比较笨拙的方法,它实现的原理很简单:先定义一个包含原始数组第一个元素的数组,然后遍历原始数组,将原始数组中的每个元素与新数组中的每个元素进行比对,如果不重复则添加到新数组中,最后返回新数组;因为它的时间复杂度是O(n^2),如果数组长度很大,效率会很低

2. Array.filter() 加 indexOf

  function distinct(a, b) {
            let arr = a.concat(b); 
            return arr.filter((item, index)=> {
                // 思想: 利用indexOf检测元素在数组中第一次出现的位置是否和元素现在的位置相等,如果不等则说明该元素是重复元素
                return arr.indexOf(item) === index
            })
        }

思想: 利用indexOf检测元素在数组中第一次出现的位置是否和元素现在的位置相等,如果不等则说明该元素是重复元素

3. ES6 中的 Set 去重

function distinct(array) {
   return Array.from(new Set(array));
}
// 使用 Set 去重
function distinct(a, b) {
  return [...new Set(a.concat(b))];
}

思想: ES6 提供了新的数据结构 Set,Set 结构的一个特性就是成员值都是唯一的,没有重复的值。

4. reduce 实现对象数组去重复

  var resources = [{
                name: "张三",
                age: "18"
            },
            {
                name: "张三",
                age: "19"
            },
            {
                name: "张三",
                age: "20"
            },
            {
                name: "李四",
                age: "19"
            },
            {
                name: "王五",
                age: "20"
            },
            {
                name: "赵六",
                age: "21"
            }
        ]
        var temp = {};
        resources = resources.reduce((prev, curv) => {
            // 如果临时对象中有这个名字,什么都不做
            if (temp[curv.name]) {
            } else {
                // 如果临时对象没有就把这个名字加进去,同时把当前的这个对象加入到prev中
                temp[curv.name] = true;
                prev.push(curv);
            }
            return prev
        }, [])
        console.log("结果", resources);

13 对象数组如何去重

const responseList = [{
                id: 1,
                a: 1
            },
            {
                id: 2,
                a: 2
            },
            {
                id: 3,
                a: 3
            },
            {
                id: 1,
                a: 4
            },
        ];
        const result = responseList.reduce((acc, cur) => {
            const ids = acc.map(item => item.id);
            return ids.includes(cur.id) ? acc : [...acc, cur];
        }, []);
        console.log(result); // -> [ { id: 1, a: 1}, {id: 2, a: 2}, {id: 3, a: 3}

14 数组中的数据根据key去重

给定一个任意数组,实现一个通用函数,让数组中的数据根据 key 排重:

 let data = [{
                id: 1,
                v: 1
            },
            {
                id: 2,
                v: 2
            },
            {
                id: 1,
                v: 1
            },
        ];
        const dedup = (data, getKey = () => {}) => {
            const dateMap = data.reduce((pre, cur) => {
                const key = getKey(cur);
                if (!pre[key]) {
                    pre[key] = cur
                }
                return pre
            }, {})
            return Object.values(dateMap)
        }

        console.log(dedup(data, (item) => item.id))
        // 以 id 作为排重 key,执行函数得到结果
        // data = [
        //   { id: 1, v: 1 },
        //   { id: 2, v: 2 },
        // ];

15 类数组转化为数组的方法

const arrayLike = document.querySelectorAll('div');
        // 1.扩展运算符
        [...arrayLike]
        // 2.Array.from
        Array.from(arrayLike)
        // 3.Array.prototype.slice
        Array.prototype.slice.call(arrayLike)
        // 4.Array.apply
        Array.apply(null, arrayLike)
        // 5.Array.prototype.concat
        Array.prototype.concat.apply([], arrayLike)

16 reduce用法汇总

array.reduce(function(total, currentValue, currentIndex, arr), initialValue);
/*
  total: 必需。初始值, 或者计算结束后的返回值。
  currentValue: 必需。当前元素。
  currentIndex: 可选。当前元素的索引;                     
  arr: 可选。当前元素所属的数组对象。
  initialValue: 可选。传递给函数的初始值,相当于total的初始值。

1. 数组求和

const arr = [12, 34, 23];
const sum = arr.reduce((total, num) => total + num);

// 设定初始值求和
const arr = [12, 34, 23];
const sum = arr.reduce((total, num) => total + num, 10);  // 以10为初始值求和

// 对象数组求和
var result = [
  { subject: 'math', score: 88 },
  { subject: 'chinese', score: 95 },
  { subject: 'english', score: 80 }
];
const sum = result.reduce((accumulator, cur) => accumulator + cur.score, 0); 
const sum = result.reduce((accumulator, cur) => accumulator + cur.score, -10);  // 总分扣除10分

2. 数组最大值

const a = [23,123,342,12];
const max = a.reduce((pre,next)=>pre>cur?pre:cur,0); // 342

3. 数组转对象

var streams = [{name: '技术', id: 1}, {name: '设计', id: 2}];
var obj = streams.reduce((accumulator, cur) => {accumulator[cur.id] = cur; return accumulator;}, {});

4. 扁平一个二维数组

var arr = [[1, 2, 8], [3, 4, 9], [5, 6, 10]];
var res = arr.reduce((x, y) => x.concat(y), []);

 

 

5. 数组去重

var newArr = arr.reduce(function (prev, cur) {
    prev.indexOf(cur) === -1 && prev.push(cur);
    return prev;
},[]);

6. 对象数组去重

const dedup = (data, getKey = () => { }) => {
    const dateMap = data.reduce((pre, cur) => {
        const key = getKey(cur)
        if (!pre[key]) {
            pre[key] = cur
        }
        return pre
    }, {})
    return Object.values(dateMap)
}

7. 求字符串中字母出现的次数

const str = 'sfhjasfjgfasjuwqrqadqeiqsajsdaiwqdaklldflas-cmxzmnha';

const res = str.split('').reduce((pre,next)=>{
 pre[next] ? pre[next]++ : pre[next] = 1
 return pre 
},{})

8. compose函数

function compose(...funs) {
    if (funs.length === 0) {
        return arg => arg;
    }
    if (funs.length === 1) {
       return funs[0];
    }
    return funs.reduce((a, b) => (...arg) => a(b(...arg)))
}

 

 

你可能感兴趣的:(javascript,开发语言,ecmascript)