我如何写我自己的“减少”函数
How do I write my own `reduce` function?
我想自己写reduce
。但在过去的4个小时里,我做不到。
var a = [10, 21, 13, 56];
function add(a, b) { return a + b }
function foo(a, b) { return a.concat(b) }
Array.prototype.reduce2 = function () {
// I do not understand how to handle the function of the inlet
// I know that I should use arguments, but I don't know how many arguments there will be
var result = 0;
for(var i = 0; i < arguments.length; i++) {
result += arguments[i];
}
return result;
};
console.log(a.reduce(add), a.reduce2(add)) // 100 100
console.log(a.reduce(add, 10), a.reduce2(add, 10)) // 110 110
是的,我知道这看起来像很多话题,但是我找不到答案。我遗漏了什么,或者做错了什么?
subject中的数组不是作为参数传递的,而是上下文(this
)。
您还需要区分是否存在起始值:
var a = [10, 21, 13, 56];
function add(a, b) { return a + b }
function foo(a, b) { return a.concat(b) }
Array.prototype.reduce2 = function (f, result) {
var i = 0;
if (arguments.length < 2) {
i = 1;
result = this[0];
}
for(; i < this.length; i++) {
result = f(result, this[i], i, this);
}
return result;
};
console.log(a.reduce(add), a.reduce2(add)) // 100 100
console.log(a.reduce(add, 10), a.reduce2(add, 10)) // 110 110
// extra test with foo:
console.log(a.reduce(foo, 'X'), a.reduce2(foo, 'X')) // X10211356 X10211356
使用ES6默认参数:
const nums = [1, 5, 5, 9];
Array.prototype.customReduce = function (callback, initial=0) {
let result = initial;
for (let i = 0; i < this.length; i++) {
result = callback(result, this[i]);
}
return result;
};
const sum = nums.customReduce((acc, value) => acc + value, 0);
console.log(sum); // 20
基于您的代码
var a = [10, 21, 13, 56];
function add(a, b) { return a + b }
function foo(a, b) { return a.concat(b) }
Array.prototype.reduce2 = function(fn, start){
var result = start !== undefined ? start : this[0];
for (var i = 0; i < this.length; i++) {
result = fn(result, this[i]);
}
return result;
};
console.log(a.reduce(add), a.reduce2(add)) // 100 100
console.log(a.reduce(add, 10), a.reduce2(add, 10)) // 110 110
console.log(a.reduce(foo, ''), a.reduce2(foo, ''));
console.log(a.reduce(foo, 'X'), a.reduce2(foo, 'X'));
我不确定我的答案是否完全回答了这个问题,但我希望这可能对某人有所帮助。
不使用原型和循环的例子:
const origArr = [2,2]
const origFunc = (p,c) => p+c
const initial = 1
const reduce = (func, array, initial) => {
const rec = (arr, acc) => {
// arr: [2, 2], [2], []
// acc: 1, 3, 5
if (!arr.length) return acc
const curr = arr[0]
const nextArr = arr.slice(1)
const nextAcc = func(acc, curr)
return rec(nextArr, nextAcc)
}
if (initial) {
return rec(array, initial)
}
return rec(array.slice(1), array[0])
}
console.log(origArr.reduce(origFunc, initial)) // 5
console.log(reduce(origFunc, origArr, initial)) // 5
和循环的例子:
const reduceLoop = (func, array, initial) => {
let acc = initial !== undefined ? initial : array[0]
let arr = initial !== undefined ? [initial, ...array] : array
for(let i=1;i<arr.length;i++) {
acc = func(acc, arr[i])
}
return acc
}
正如你所看到的,在第一个例子中,我们没有分配变量,我们只有一些常量,但在循环的例子中,我们分配了acc
变量
下面的代码将传递的数组简化为单个值。需要传递一个函数,告诉数组需要做什么,如果需要,传递一个初始值。
Array.prototype.myFunction = function(fn,initial) {
let arayEl = this;
console.log(arayEl);
let total = initial || 0;
for(let i=0;i<arayEl.length;i++) {
total = fn(total,arayEl[i]);
}
return total;
}
console.log([1,2,3].myFunction(function(total,x){return total +x},10));
console.log([1,2,3].reduce(function(total,x){return total +x},10));
console.log([1,2,3].myFunction(function(total,x){return total * x},10));
console.log([1,2,3].reduce(function(total,x){return total * x},10));
- myFunction是一个自定义的reduce函数,它接受一个回调函数(fn)和一个可选的初始值。它就像减速器一样工作。
- 回调函数 function(total,x){return total + x}作为参数传递给myFunction,然后减少为单个值。这里我们可以执行任何类似于reduce的操作,而不是add。
const reduceV1 = (list, cb, intial) => {
let memo = intial;
for (let i = 0; i < list.length; i++) {
if (i === 0 && memo === undefined) {
memo = list[0];
} else {
memo = cb(list[i], memo);
}
}
return memo;
};
function sumV1(n, sum) {
return n + sum;
}
console.log(reduceV1([1, 2], sumV1));
console.log(reduceV1([1, 2,3], sumV1,0));
实际缩减函数:
const list = [1,2,3,4,5];
const sum = list => list.reduce((total, val)=> total+val, 0)
console.log(sum(list));
如果我们仔细看,我们需要三样东西:一个要迭代的列表,初始值和一个reduce函数
const reduceHelper = (list, initialValue, reducer) => {
// If the list is empty we will just return initial value
if(list.length === 0) {
return initialValue;
} else {
const [first, ...rest] = list;
const updatedAcc = reducer(initialValue, first);
return reduceHelper(rest, updatedAcc, reducer);
}
}
// test it
const list = [1,2,3,4,5];
console.log( myReduce(list, 0, (total, val) => total + val))
思路是一样的。我们可以遵循同样的思路,编写不同的reduce函数来计数单词.......
Array.prototype.myReduce = function(callback, initialValue) {
var a = initialValue;
for(let i=0; i<this.length;i++){
callback(a=a+this[i]);
}
return a;
}
var arr = [1,2,3,4,5];
var result = arr.myReduce((next,prev) =>next+prev,10);
console.log(result); //25
const arr = [1,2,2,4];
Array.prototype.handReducer = function(cb,value) {
this.forEach(ele => value = cb(ele,value))
console.log(value)//9
return value;
}
const cb = (arr,value) => arr + value;
const new_arr = arr.handReducer(cb,0)
Array.prototype.customReduce = function (callback, initial) {
const arr = this;
for (let i = 0; i < arr.length; i++) {
if (initial === undefined && i === 0) {
initial = arr[0];
continue;
}
initial = callback(initial, arr[i], i);
}
return initial;
}
var a = [10, 21, 13, 56];
function add(a, b) { return a + b }
Array.prototype.reduce2 = function(fn, start){
var result = start !== undefined ? start : this[0];
for (var i = 1; i < this.length; i++) {
result = fn(result, this[i]);
}
return result;
};
console.log(a.reduce(add), a.reduce2(add))
相关文章:
- 如何通过ajax增加/减少PHP变量值并重新加载函数
- 函数比javascript中的步进器增加/减少更多
- 如何减少Crossfilter组函数创建的bucket数量
- 在 mongo map 中调用外部 javascript 函数(对象)或减少上下文的可能方法
- 使用 map 函数时减少 JavaScript 代码
- Javascript函数声明野牛语法减少/减少错误
- 我可以将函数变成变量以减少我的代码(请 JavaScript 代码调试)
- 函数在Javascript中不起作用(增加/减少按钮)
- 减少删除重复项的函数 - javascript
- 如何减少函数表达式的数量
- 在函数调用中设置和减少变量
- 如何在Javascript中重写函数时减少冗余代码
- 如何结合两个jQuery函数的代码来减少执行时间?
- 我如何写我自己的“减少”函数
- 减少jQuery函数
- 如何减少Javascript内部函数变量的作用域
- 函数减少esizeimage()对多个图像进行翻转
- 用javascript减少冗余函数
- Javascript函数增加/减少cellValue
- 为什么在JavaScript中,数组在第一次迭代后会减少函数更改参数