数组

js实现Map()

语法

array.map(function(currentValue, index, arr), thisValue)
map() 方法返回一个新数组,数组中的元素为原始数组元素按顺序依次调用函数处理后的值。
注意: map() 不会对空数组进行检测

参数

currentValue(必须): 当前元素的值
index (可选): 当前元素的索引值
arr (可选): 当前元素属于的数组对象
thisValue(可选) 传递给回调函数,用作 “this” 的值。

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Array.prototype.myMap = function (callback, thisArgs) {
// 通过对this引用,拿到调用回调函数的数组
let arr = this;
// 检查传递的参数是否正确
if (!Array.isArray(arr) || !arr.length || typeof callback !== 'function') {
return [];
} else {
// 为了不改变原数组,调用此函数时,创建一个 temp 数组
let temp = [];

for (let i = 0; i < arr.length; i++) {
// 利用call() 函数。改变callback的this指向,
// 指向当前传入的thisArg,传参执行方法
let result = callback.call(thisArgs, arr[i], i, arr);
// 将 callback 返回的结果 push 到 temp 数组中
temp.push(result);
}
return temp;
}
}

js实现Filter()

语法

array.filter(function(currentValue,index,arr), thisValue)
filter() 方法创建一个新数组,新数组中的元素是:符合检查函数中的条件的所有元素。

注意: filter() 不会改变原始数组。

参数

对每一项执行的函数,接收三个参数:
currentValue(必须): 数组项的值
index(可选): 数组项的下标
arr(可选): 数组对象本身
thisValue(可选): 指定 this 的作用域对象

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Array.prototype.myFilter = function (callback, thisArgs) {
// 通过对this引用,拿到调用回调函数的数组
let arr = this;
// 检查传递的参数是否正确
if (!Array.isArray(arr) || !arr.length || typeof callback !== 'function') {
return [];
} else {
// 为了不改变原数组,调用此函数时,创建一个 temp 数组
let temp = [];

for (let i = 0; i < arr.length; i++) {
// 利用call() 函数改变callback的this指向,
// 指向当前传入的thisArg,传参执行callback方法
let result = callback.call(thisArgs, arr[i], i, arr);
// 若通过函数检测,说明当前数组元素符合要求,push到temp数组中
if(result) temp.push(arr[i]);
}
return temp;
}
}

js实现Reduce()

语法

array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
reduce() 方法接收一个函数,一个用来执行每个数组元素的函数。数组中的每个值(从左到右)开始缩减,最终计算为一个值。
initialValue (可选): 传递给函数的初始值
注意: reduce() 对于空数组,是不会执行回调函数的

参数

total(必须): 初始值, 或者计算结束后的返回值。
currentValue(必须): 当前元素
currentIndex(可选): 当前元素的索引
arr(可选):当前元素所属的数组对象
initialValue(可选): 传递给函数的初始值

思路

判断参数是否异常
如何判断 initialValue 参数是否存在:arguments.length
如何判断数组元素为 empty:hasOwnProperty
不存在 initialValue 时的处理逻辑:
没有初始值参数时,reduce 会将第一个非 empty 的值作为初始值,并从该值的下一个值开始执行 reducer。

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Array.prototype.myReduce = function(reducer, initialValue) {

// 参数异常
if (arguments.length === 0) {
throw new TypeError('undefined is not a function');
}
// reducer 不是函数类型
if (typeof arguments[0] !== 'function') {
throw new TypeError(`${arguments[0]} is not a function`);
}
// 既没有传入initialValue,数组中也没有值
if (arguments.length === 1 && this.length === 0) {
throw new TypeError('Reduce of empty array with no initial value');
}
// 通过 arguments.length 判断是否存在 initialValue
const hasInitial = arguments.length > 1;
let value = hasInitial ? initialValue : this[0];
for (let i = hasInitial ? 0 : 1; i < this.length; i++) {
value = reducer.call(undefined, value, this[i], i, this);
}
return value;
}

用法

  • 计算数组中每个元素出现的次数
1
2
3
4
5
6
7
8
9
10
let names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
let nameNum = names.myReduce((pre,cur)=>{
if(cur in pre){
pre[cur]++
}else{
pre[cur] = 1
}
return pre
},{})
console.log(nameNum); //{Alice: 2, Bob: 1, Tiff: 1, Bruce: 1}
  • 数组求和,求乘积
1
2
3
4
5
6
var  arr = [1, 2, 3, 4];
var sum = arr.myReduce((x,y)=>x+y)
var mul = arr.myReduce((x,y)=>x*y)
console.log( sum ); //求和,10
console.log( mul ); //求乘积,24

  • 数组去重

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    let arr = [1,2,3,4,4,1]
    let newArr = arr.reduce((pre,cur)=>{
    if(!pre.includes(cur)){
    // 注意此处不用push(改变原数组),而使用concat(返回新数组)。
    // pre.push(cur) 返回的是添加后的数组长度,是一个number
    return pre.concat(cur)
    }else{
    return pre
    }
    },[])
    console.log(newArr);// [1, 2, 3, 4]

  • 多维数组转化为一维

    1
    2
    3
    4
    5
    6
    7
    8
    let arr = [[0, 1], [2, 3], [4,[5,6,7]],[6,[[33],[1,5]]]];
    function func (arr){
    return arr.reduce((prev,cur)=>prev.concat(Array.isArray(cur) ? func(cur) : cur),[])

    }

    console.log(func(arr));

查看评论