Reduce its sharp, solve its dispute, and its light, with its dust.
Introduction to the
Array.prototype has a lot of methods, can be very convenient to implement a variety of loop, filter Array to do a lot of processing, here mainly record myself how to implement several methods map, forEach, filter, reduce, I’m not going to talk much about how to use it because there’s a lot of discussion about Array in MDN and other people’s articles.
To realize the reduce
Reduce takes two arguments. The first argument is a callback method and the second argument is an initialValue, initialValue. The general implementation steps are as follows:
- Determines whether the calling method itself is Array
- Declare the variables to use
- Check if there is an initial value. If there is no initial value, fetch it from its own array and jump out of the loop
- Loop through callback
Array.prototype.selfReduce = function(callback, initalValue) {
// Cannot be null calling method
if (this= = =null) {
throw new TypeError(
"Array.prototype.reduce" + "called on null or undefined"
);
}
// The first argument must be function
if (typeofcallback ! = ="function") {
throw new TypeError(callback + " is not a function");
}
// Declare the variables to use
// The array to loop through
let arr = Array.prototype.slice.call(this);
let _len = arr.length;
// Result array
let res = [];
// The initial array index defaults to 0
let startIndex = 0;
// Check whether there is an initial value initalValue
if (initalValue === undefined) {
// If the initial value is undefined, the loop finds a value in the array and exits the loop
// Filter the sparse values
for (let i = 0; i < _len; i++) {
if(! arr.hasOwnProperty(i)) {continue;
} else {
startIndex = i;
res = arr[i];
break; }}}else {
res = initalValue;
}
// Get the initial value in the previous step, loop through the incoming callback function, and filter the loose values
for (let i = startIndex++; i < arr.length; i++) {
if(! arr.hasOwnProperty(i)) {continue;
}
res = callback.call(null, res, arr[i], i, this);
}
return res;
};
Copy the code
Test selfReduce and Reduce methods to see if they behave the same:
var aTest = [1.2.3.4.5];
arr.reduce((prev, next) = > {
return prev + next;
}, 0); / / 15
arr.selfReduce((prev, next) = > {
return prev + next;
}, 0); / / 15
Copy the code
You can also check out the official MDN Reduce Polyfill.
To realize the map
Map is implemented in two ways, one through the for loop and the other through reduce.
For loop implementation
Array.prototype.selfMap = function(callback, context) {
// Cannot be null calling method
if (this= = =null) {
throw new TypeError(
"Array.prototype.reduce" + "called on null or undefined"
);
}
// The first argument must be function
if (typeofcallback ! = ="function") {
throw new TypeError(callback + " is not a function");
}
// Declare the variables to use
let arr = Array.prototype.slice.call(this);
let _len = arr.length;
let aMap = [];
// loop call
for (let i = 0; i < _len; i++) {
// Filter the sparse values
if(! arr.hasOwnProperty(i)) {continue;
}
aMap[i] = callback.call(context, arr[i], i, this);
}
return aMap;
};
Copy the code
To test whether selfMap and Map are consistent, the code is as follows:
var aTest = [1.2.3.4.5];
aTest.map(item= > {
return item * 2;
}); // [2, 4, 6, 8, 10]
aTest.selfMap(item= > {
return item * 2;
}); // [2, 4, 6, 8, 10]
Copy the code
Reduce implementation
Array.prototype.reduceMap = function(callback, context) {
// Cannot be null calling method
if (this= = =null) {
throw new TypeError(
"Array.prototype.reduce" + "called on null or undefined"
);
}
// The first argument must be function
if (typeofcallback ! = ="function") {
throw new TypeError(callback + " is not a function");
}
// Get the array
let aMap = Array.prototype.slice.call(this);
// Use reduce to implement loops
return aMap.reduce((pre, cur, index) = > {
// Concatenate the result of the last loop with the current result
// loop through callback
return [...pre, callback.call(context, cur, index, this)]; } []); };Copy the code
To test whether the implementation of reduceMap and MAP are consistent, the code is as follows:
var aTest = [1.2.3.4.5];
aTest.map(item= > {
return item * 2;
}); // [2, 4, 6, 8, 10]
aTest.reduceMap(item= > {
return item * 2;
}); // [2, 4, 6, 8, 10]
Copy the code
The filter implementation
Filter is also used many times, so I won’t go into details here. Let’s look at two implementations:
For loop implementation
Array.prototype.selfFilter = function(callback, context) {
// Cannot be null calling method
if (this= = =null) {
throw new TypeError(
"Array.prototype.reduce" + "called on null or undefined"
);
}
// The first argument must be function
if (typeofcallback ! = ="function") {
throw new TypeError(callback + " is not a function");
}
// Get the array
let aArr = Array.prototype.slice.call(this);
let _len = aArr.length;
let aFArr = [];
// loop through callback
for (let i = 0; i < _len; i++) {
if(! aArr.hasOwnProperty(i)) {continue;
}
callback.call(context, aArr[i], i, this) && aFArr.push(aArr[i]);
}
return aFArr;
};
Copy the code
Reduce implementation
Array.prototype.reduceFilter = function(callback, context) {
// Cannot be null calling method
if (this= = =null) {
throw new TypeError(
"Array.prototype.reduce" + "called on null or undefined"
);
}
// The first argument must be function
if (typeofcallback ! = ="function") {
throw new TypeError(callback + " is not a function");
}
// Get the array
let aArr = Array.prototype.slice.call(this);
// loop through callback
aArr.reduce((pre, cur, index) = > {
return callback.call(context, cur, index, this)? [...pre, cur] : [...pre]; } []);return aArr;
};
Copy the code
The test code
var aTest = [1.2.3.4.5.6];
aTest.filter(item= > {
return item > 2;
});
aTest.selfFilter(item= > {
return item > 2;
});
aTest.reduceFilter(item= > {
return item > 2;
});
Copy the code
To realize the forEach
For loop implementation
Array.prototype.selfForeach = function(callback, context) {
// Cannot be null calling method
if (this= = =null) {
throw new TypeError(
"Array.prototype.reduce" + "called on null or undefined"
);
}
// The first argument must be function
if (typeofcallback ! = ="function") {
throw new TypeError(callback + " is not a function");
}
// Get the array
let arr = Array.prototype.slice.call(this);
let _len = arr.length;
for (let i = 0; i < _len; i++) {
callback.call(context, arr[i], i, arr);
}
return arr;
};
Copy the code
Reduce cycle implementation
Array.prototype.reduceForeach = function(callback, context) {
// Cannot be null calling method
if (this= = =null) {
throw new TypeError(
"Array.prototype.reduce" + "called on null or undefined"
);
}
// The first argument must be function
if (typeofcallback ! = ="function") {
throw new TypeError(callback + " is not a function");
}
// Get the array
let arr = Array.prototype.slice.call(this);
arr.reduce((pre, cur, index) = > {
return [...pre, callback.call(context, cur, index, this)]; } []); };Copy the code
conclusion
Basically understand how to implement, whether using for or reduce implementation, basically there is no big difference. Writing is not easy, if you like likes, attention
reference
Array.prototype.reduce()
28 JavaScript Skills a qualified intermediate front-end engineer needs to master
JS array. reduce implements array. map and array. filter