如何使用 reduce 和 range 编写阶乘函数?
How can I write the factorial function with reduce and range?
function range(start, end) {
var acc = [];
for (var i = start; i < end; i++) {
acc.push(i);
}
return acc;
}
使用范围函数和reduce方法,我需要重写阶乘函数。
function factorial(n) {
// YOUR CODE HERE
}
有人提示我先在 forEach 中编写函数,然后用 range 和 reduce 重写它。这是我的尝试。
function factorial(n){
var product = 1;
n.forEach(function(x){
if(x===0){
return 1;}
product *= factorial(x-1);
});
return product;
}
factorial(4);
那是我的尝试。我知道这很乱,但我的问题是,当 n 只是一个数字而 forEach 用于数组时,我如何使用 forEach?因为他们要我先使用 each 来编写阶乘函数,所以我需要使用基本案例,对吗?我还查看了 MDN 并尝试通过遵循他们的累加器 + currentValue 语法来理解 reduce 并提出了这个伪代码。
function factorial(n){
n.reduce(function(x){
x*range;
});
}
factorial(5)
再一次,我不明白如果参数不是数组,我该如何使用 reduce。
当你说 forEach is for Arrays but n is a number
时,你就明白了。所以你需要构建你将循环(然后减少)的数组。
var n = 10;
var i = 0;
//use your "range" function to define an array from 2 to end.
var z = range(2, n + 1);
//Now we have an array we can reduce with multiplication initializing the accumulator to 1.
z.reduce(function(a,b){return a*b;}, 1);
reduce 中的函数只是乘法,第二个参数初始化累加器。
这里对0或1不需要特殊处理,因为构造的数组将为空,reduce只是return初始值1。
解决这个问题有两个步骤,首先是生成一个数组以使用 reduce 方法,第二个是实际使用 reduce 方法找到我们的阶乘答案。
我们可以使用提供给我们的范围方法来完成第一步。 range 方法 returns 一个包含最小值(含)和最大值(不含)之间的所有整数值的数组。例如,如果我们调用 range(1,5)
,它将 return [1,2,3,4]
。当我们想要执行阶乘运算时,我们想要将所有先前的整数值 包括 当前值相乘。要获取所有先前值和当前值的数组,我们可以使用
var factors = range(1,n+1);
在阶乘函数的开头。
现在我们有了所有的因数,我们可以使用 reduce 方法将它们相乘。 reduce 方法将按顺序对数组的每个值执行提供的函数。在这种情况下,我们想将所有因素相乘。我们可以使用
var multFactors = factors.reduce(function(a,b){
return a*b;
},1);
将数组中的每个值相乘。通过使用 1
作为 reduce 方法的第二个参数,我们确保 factorial(0)
不会导致任何错误(感谢 @Eterm 注意到这一点)
现在剩下的就是 return multFactors。
当所有这些放在一起时,你会得到这个
function range(start, end) {
var acc = [];
for (var i = start; i < end; i++) {
acc.push(i);
}
return acc;
}
function factorial(n) {
var factors = range(1,n+1);
var multFactors = factors.reduce(function(a,b){
return a*b;
},1);
return multFactors;
}
编辑:
如果你想避免出现负阶乘的错误,你可以对 n 应用绝对值函数。
为此,我们可以更改
var factors = range(1,n+1);
进入
var factors = range(1, Math.abs(n)+1);
取负数的阶乘应该是未定义的,但是对于这一新行,我们通过将数字设为正数来避免任何错误。如果你想保留阶乘的符号,你可以在你设置 multFactors 之后添加这些行,但在你 return 它之前。
if(n < 0)
multFactors *= -1;
完成后,你会得到这个(现在有评论,因为它更长)
function range(start, end) {
var acc = [];
for (var i = start; i < end; i++) {
acc.push(i);
}
return acc;
}
function factorial(n) {
//Get the factors
var factors = range(1, Math.abs(n)+1);
//Multiply all of the factors together
var multFactors = factors.reduce(function(a,b){
return a*b;
},1);
//if n was negative make the result negative
if(n < 0)
multFactors *= -1;
//return the calculated result
return multFactors;
}
希望这对您有所帮助。
您可以使用 Array
.apply
并为给定的开始值和结束值创建一个包含范围。
然后乘法归约。
function range(start, end) {
return Array.apply(null, { length: end - start + 1 }).map(function (_, i) { return start + i; });
}
function multiply(a, b) { return a * b; }
var array = range(3, 7),
product = array.reduce(multiply);
console.log(array);
console.log(product);
console.log(range(1, 10).reduce(multiply));
.as-console-wrapper { max-height: 100% !important; top: 0; }
只需Array.prototype.reduce()
您就可以进行如下操作;
function factorial(a){
return Array(a[1]-a[0]).fill()
.reduce((r,_,i) => r *= a[0]+i+1, a[0] ? a[0] : 1);
}
console.log(factorial([0,10]));
console.log(factorial([2,5]));
这里还有很多其他答案可以提供解决问题的实用方法。相反,我的回答是故意不切实际的(如 JavaScript 中所写),但旨在教给您其他东西。
这个答案受到只有单参数、单表达式函数的 lambda 演算的影响。剖析这段代码会让你对高阶过程有深刻而深刻的理解。
我们将首先定义 Y 组合器,然后使用 Y
实现 range
和 reduce
。那么我们终于可以实现factorial
.
const U =
f => f (f)
const Y =
U (h => f => f (x => h (h) (f) (x)))
const range =
Y (h => acc => x => y =>
x > y
? acc
: h ([...acc, x]) (x + 1) (y)
)
([])
const reduce =
Y (h => f => acc => ([x, ...xs]) =>
x == null
? acc
: h (f) (f (acc) (x)) (xs)
)
const mult =
x => y => y * x
const factorial =
x => reduce (mult) (1) (range (1) (x))
console.log (factorial (5)) // 120
console.log (factorial (6)) // 720
console.log (factorial (7)) // 5040
我会选择这样的东西:
const range = (start, end) => Array.from(
{ length: end - start },
(_, n) => start + n,
);
const product = (nums) => nums.reduce((a, b) => a * b);
const inc = (n) => n + 1;
const factorial = (num) => product(
range(1, inc(num)),
);
const expect = (given) => ({
toEqual(expected) {
console.assert(given === expected, `${given} === ${expected}`);
}
});
expect(factorial(5)).toEqual(120);
expect(factorial(6)).toEqual(720);
function range(start, end) {
var acc = [];
for (var i = start; i < end; i++) {
acc.push(i);
}
return acc;
}
使用范围函数和reduce方法,我需要重写阶乘函数。
function factorial(n) {
// YOUR CODE HERE
}
有人提示我先在 forEach 中编写函数,然后用 range 和 reduce 重写它。这是我的尝试。
function factorial(n){
var product = 1;
n.forEach(function(x){
if(x===0){
return 1;}
product *= factorial(x-1);
});
return product;
}
factorial(4);
那是我的尝试。我知道这很乱,但我的问题是,当 n 只是一个数字而 forEach 用于数组时,我如何使用 forEach?因为他们要我先使用 each 来编写阶乘函数,所以我需要使用基本案例,对吗?我还查看了 MDN 并尝试通过遵循他们的累加器 + currentValue 语法来理解 reduce 并提出了这个伪代码。
function factorial(n){
n.reduce(function(x){
x*range;
});
}
factorial(5)
再一次,我不明白如果参数不是数组,我该如何使用 reduce。
当你说 forEach is for Arrays but n is a number
时,你就明白了。所以你需要构建你将循环(然后减少)的数组。
var n = 10;
var i = 0;
//use your "range" function to define an array from 2 to end.
var z = range(2, n + 1);
//Now we have an array we can reduce with multiplication initializing the accumulator to 1.
z.reduce(function(a,b){return a*b;}, 1);
reduce 中的函数只是乘法,第二个参数初始化累加器。
这里对0或1不需要特殊处理,因为构造的数组将为空,reduce只是return初始值1。
解决这个问题有两个步骤,首先是生成一个数组以使用 reduce 方法,第二个是实际使用 reduce 方法找到我们的阶乘答案。
我们可以使用提供给我们的范围方法来完成第一步。 range 方法 returns 一个包含最小值(含)和最大值(不含)之间的所有整数值的数组。例如,如果我们调用 range(1,5)
,它将 return [1,2,3,4]
。当我们想要执行阶乘运算时,我们想要将所有先前的整数值 包括 当前值相乘。要获取所有先前值和当前值的数组,我们可以使用
var factors = range(1,n+1);
在阶乘函数的开头。
现在我们有了所有的因数,我们可以使用 reduce 方法将它们相乘。 reduce 方法将按顺序对数组的每个值执行提供的函数。在这种情况下,我们想将所有因素相乘。我们可以使用
var multFactors = factors.reduce(function(a,b){
return a*b;
},1);
将数组中的每个值相乘。通过使用 1
作为 reduce 方法的第二个参数,我们确保 factorial(0)
不会导致任何错误(感谢 @Eterm 注意到这一点)
现在剩下的就是 return multFactors。
当所有这些放在一起时,你会得到这个
function range(start, end) {
var acc = [];
for (var i = start; i < end; i++) {
acc.push(i);
}
return acc;
}
function factorial(n) {
var factors = range(1,n+1);
var multFactors = factors.reduce(function(a,b){
return a*b;
},1);
return multFactors;
}
编辑:
如果你想避免出现负阶乘的错误,你可以对 n 应用绝对值函数。
为此,我们可以更改
var factors = range(1,n+1);
进入
var factors = range(1, Math.abs(n)+1);
取负数的阶乘应该是未定义的,但是对于这一新行,我们通过将数字设为正数来避免任何错误。如果你想保留阶乘的符号,你可以在你设置 multFactors 之后添加这些行,但在你 return 它之前。
if(n < 0)
multFactors *= -1;
完成后,你会得到这个(现在有评论,因为它更长)
function range(start, end) {
var acc = [];
for (var i = start; i < end; i++) {
acc.push(i);
}
return acc;
}
function factorial(n) {
//Get the factors
var factors = range(1, Math.abs(n)+1);
//Multiply all of the factors together
var multFactors = factors.reduce(function(a,b){
return a*b;
},1);
//if n was negative make the result negative
if(n < 0)
multFactors *= -1;
//return the calculated result
return multFactors;
}
希望这对您有所帮助。
您可以使用 Array
.apply
并为给定的开始值和结束值创建一个包含范围。
然后乘法归约。
function range(start, end) {
return Array.apply(null, { length: end - start + 1 }).map(function (_, i) { return start + i; });
}
function multiply(a, b) { return a * b; }
var array = range(3, 7),
product = array.reduce(multiply);
console.log(array);
console.log(product);
console.log(range(1, 10).reduce(multiply));
.as-console-wrapper { max-height: 100% !important; top: 0; }
只需Array.prototype.reduce()
您就可以进行如下操作;
function factorial(a){
return Array(a[1]-a[0]).fill()
.reduce((r,_,i) => r *= a[0]+i+1, a[0] ? a[0] : 1);
}
console.log(factorial([0,10]));
console.log(factorial([2,5]));
这里还有很多其他答案可以提供解决问题的实用方法。相反,我的回答是故意不切实际的(如 JavaScript 中所写),但旨在教给您其他东西。
这个答案受到只有单参数、单表达式函数的 lambda 演算的影响。剖析这段代码会让你对高阶过程有深刻而深刻的理解。
我们将首先定义 Y 组合器,然后使用 Y
实现 range
和 reduce
。那么我们终于可以实现factorial
.
const U =
f => f (f)
const Y =
U (h => f => f (x => h (h) (f) (x)))
const range =
Y (h => acc => x => y =>
x > y
? acc
: h ([...acc, x]) (x + 1) (y)
)
([])
const reduce =
Y (h => f => acc => ([x, ...xs]) =>
x == null
? acc
: h (f) (f (acc) (x)) (xs)
)
const mult =
x => y => y * x
const factorial =
x => reduce (mult) (1) (range (1) (x))
console.log (factorial (5)) // 120
console.log (factorial (6)) // 720
console.log (factorial (7)) // 5040
我会选择这样的东西:
const range = (start, end) => Array.from(
{ length: end - start },
(_, n) => start + n,
);
const product = (nums) => nums.reduce((a, b) => a * b);
const inc = (n) => n + 1;
const factorial = (num) => product(
range(1, inc(num)),
);
const expect = (given) => ({
toEqual(expected) {
console.assert(given === expected, `${given} === ${expected}`);
}
});
expect(factorial(5)).toEqual(120);
expect(factorial(6)).toEqual(720);