数组函数的实现
1. 内置方法 - 排序函数sort():
- 参数:函数(规定排序的顺序),可选
- 返回值:对数组的引用【改变原数组】
- 使用方式:
var points = [40,100,1,5,25,10];
points.sort();// 结果是[1, 10, 100, 25, 40, 5]
points.sort(function(a,b){return a-b});
⚠⚠️:默认排序顺序为按字母升序。当数字是按字母顺序排列时"40"将排在"5"前面。使用数字排序,你必须通过一个函数作为参数来调用。
- 手写算法:快排
/**
* @param {Array} arr
* @param {Function} fn
* @return {Array}
*/
var sortBy = function(arr, fn) {
let len = arr.length;
// 递归结束条件
if(len<=1) return arr;
let mid = Math.floor(len/2);
let left=[];
let right =[];
for(let i=0; i<len;i++){
// 中间值不要放进切分的数组中
if(fn(arr[i]) === fn(arr[mid])) continue;
if(fn(arr[i])<fn(arr[mid])){
left.push(arr[i])
}else{
right.push(arr[i])
}
}
return [...sortBy(left,fn),arr[mid],...sortBy(right,fn)];
};
2. 内置方法 - 过滤函数 filter():
- 不检测空数组
- 参数:
- 函数:必须
- 函数参数:
- 当前值,索引,当前数组
- 函数参数:
- thisValue:可选,省略的话this是undefined
- 函数:必须
- 返回值:新数组,[不改变] 原数组
var filter = function(arr, fn) {
let filteredArr =[];
for(let i=0; i< arr.length;i++){
if(fn(arr[i], i)){
filteredArr.push(arr[i])
}
}
return filteredArr;
};
3. 内置方法 - 映射函数map
/**
* @param {number[]} arr
* @param {Function} fn
* @return {number[]}
*/
var map = function(arr, fn) {
let returnedArray = [];
for(let i =0; i<arr.length; i++){
const newItem = fn(arr[i],i)
returnedArray.push(newItem);
}
return returnedArray;
};
4. 内置方法 - 归约函数reduce
- 还有个reduceRight
/**
* @param {number[]} nums
* @param {Function} fn
* @param {number} init
* @return {number}
*/
var reduce = function(nums, fn, init) {
let val = init;
if(nums.length ===0 ){
return val;
}
for(var i=0; i<nums.length; i++){
val = fn(val,nums[i]);
}
return val;
};
5. 复合函数
请你编写一个函数,它接收一个函数数组
[f1, f2, f3,…, fn],并返回一个新的函数fn,它是函数数组的 复合函数 。
[f(x), g(x), h(x)]的 复合函数 为fn(x) = f(g(h(x)))。
恒等函数f(x) = x
var compose = function(functions) {
return function(x) {
for(let i =functions.length-1; i>=0 ; i--){
x = functions[i](x);
}
return x;
}
};
6. 分块数组lodash 的函数 _.chunk
/**
* @param {Array} arr
* @param {number} size
* @return {Array[]}
*/
var chunk = function(arr, size) {
let index =0 ;
let resultArr=[];
let row = [];
while(index< arr.length){
row.push(arr[index]);
if(row.length === size){
resultArr.push([...row])
row = [];
}
index++;
}
row.length && resultArr.push([...row])
return resultArr;
};
原型
1. last 函数
注意:原型上的this指向调用的对象,所以这里this是arr
Array.prototype.last = function() {
return this.length ? this[this.length-1] : -1
};
/**
* const arr = [1, 2, 3];
* arr.last(); // 3
*/
2. 包装函数
构造函数中的this是指向实例。构造函数命名首字母大写
// 构造函数,需要new 声明
var ArrayWrapper = function(nums) {
this.nums = nums;
};
// 隐形转换
ArrayWrapper.prototype.valueOf = function() {
return this.nums.reduce((pre,cur)=>pre+cur, 0);
}
ArrayWrapper.prototype.toString = function() {
return `[${this.nums.join()}]`
}
/**
* const obj1 = new ArrayWrapper([1,2]);
* const obj2 = new ArrayWrapper([3,4]);
// console.log(obj1.nums): [1,2]
* obj1 + obj2; // 10
* String(obj1); // "[1,2]"
* String(obj2); // "[3,4]"
*/