使用 .map 分解数组中的所有数字
Posted
技术标签:
【中文标题】使用 .map 分解数组中的所有数字【英文标题】:Factorialise all numbers in array with .map 【发布时间】:2019-12-19 00:15:34 【问题描述】:我有一个数字数组,例如[2, 4, 5] 并且必须在新数组中获取阶乘。例如。 [2, 24, 120]
如您所见,我正在使用 .map 对数组中的每个整数执行该函数,但是,这不起作用吗?我认为递归函数有问题?
谢谢。
function getFactorials(nums)
if(nums > 1)
factarr = nums.map(x => x * (nums - 1));
return factarr;
【问题讨论】:
我不是数学高手,但是阶乘(4)应该是4*3*2*1吧?如果是这样,你没有这样做。 无阶乘 4!是 4x3x2x1 :) 对不起,是那个意思。但是,您的代码没有这样做;)nums
应该是数组还是数字?
"我认为递归函数有问题"这里没有递归函数。
【参考方案1】:
您可以使用阶乘函数并映射值。
该函数具有递归样式,并检查值。如果值为零,则函数以 1 退出。否则返回实际值与递减函数调用结果的乘积。
检查使用将 falsy 隐式转换为 conditional (ternary) operator ?:
的布尔值。
const fact = n => n ? n * fact(n - 1) : 1;
var array = [2, 4, 5],
result = array.map(fact);
console.log(result);
【讨论】:
谢谢!我会试试这个。没想到要分开他们:) 这行得通:) 你能解释一下第一行发生的事情吗?将不胜感激 @Tonyfact
是一个签名接受参数 (n) 的函数。如果 (n) 是真实的(因此,如果它不是 0,在您的特定场景中),它返回 n 乘以 fact(n - 1),否则返回 1。基本上,它递归地返回 n * fact(n-1)直到 n 不再真实。
@Nina_Scholz 三元运算符应该有这个条件const fact = n => (n > 1) ? n * fact(n - 1) : 1;
否则它可能会抛出StackOverlow
负数:)
@VedantTerkar, factorial
只为正整数定义。【参考方案2】:
只需创建一个计算给定数字的阶乘的函数,然后将其用作map
函数的回调。
由于主要部分是计算因子的方式,这里有两种方式来完成这项任务
Factoriel函数迭代方式:
const fact = n =>
let f = 1,
i = n;
for(; i > 1; i--) f *= i;
return f;
;
console.log(fact(4)); /** outpuut: 24 **/
Factoriel函数递归方式:
const fact = n => n > 1 ? n * fact(n - 1) : n;
console.log(fact(4)); /** outpuut: 24 **/
最后的代码:
const arr = [2, 4, 5],
fact = n => n > 1 ? n * fact(n - 1) : n,
factArr = arr.map(i => fact(i));
console.log(factArr); /** output: [2, 24, 120] **/
【讨论】:
不客气,如果需要,请随时寻求解释。【参考方案3】:你做错了递归,我的方法是将阶乘计算器定义为一个单独的函数:
function getFactorials(nums)
function factorial(n)
return n === 0 ? 1 : n * factorial(n - 1);
return nums.map(x => factorial(x));
console.log(getFactorials([0, 1, 2, 3, 4, 5 ,6]));
【讨论】:
【参考方案4】:您需要计算数组中的每个阶乘,您当前的代码没有这样做。考虑以下示例:
function factorial(num)
if (num === 0 || num === 1)
return 1;
else
return num * factorial(num - 1);
const facts = [2, 4, 5];
const factsArr = facts.map(num => factorial(num));
在您的代码中,您只是将数组的每个成员乘以数组本身。
【讨论】:
【参考方案5】:我没有递归地执行此操作,而是从使用 reduce()
的 @Amin Jafari 中获取解决方案。此函数比递归解决方案更快。
首先我们生成一个数组。我们通过使用Array(n + 1)
来做到这一点。 n
是阶乘,例如对于6!
,我们的n
将是6
。我们使用keys()
获得索引,但Array()
本身只返回一个真正的空数组,keys()
只返回一个迭代器。所以我们传播它并将其结果放入一个新数组中。因此,我们有例如[0,1,2,3,4,5,6]
(对于 n + 1
和 n = 6
)。我们用slice(1)
排除0。
之后我们终于申请reduce
。 Reduce 迭代所有元素,在跟踪累加器的同时应用一个函数。我们这里的蓄能器是当前的产品。所以发生的事情是计算1 * 2
,并将结果保存在我们的累加器a
中。然后我们将a
与下一个值相乘,即2 * 2*
,直到我们遍历整个自生成数组。
此函数基于reduce
,然后我们可以使用map()
转换原始数组中的每个值。
const factorial = n => [...Array(n+1).keys()].slice(1).reduce((a,c) => a * c),
data = [2, 4, 5];
let res = data.map(v => factorial(v));
console.log(res);
【讨论】:
【参考方案6】:我知道这篇文章已经有很多答案了,但我可能要补充一些东西:
如果您计划大量使用递归函数来计算阶乘,假设您在浏览器游戏中每 0.5 秒需要一次,您会注意到它消耗大量资源,主要是你的时间?。
我的提议是:
计算阶乘一次 将它们存储在应用状态中 查找而不是计算它们示例代码(基于 Nina Scholz 的回答):
// create this earlier, put it in the application state
const state = lookupFact: []
const fact = n => n ? n * fact(n - 1) : 1;
// only calculate the factorials once
function lookupFact(par)
if (state.lookupFact.length == 0)
for (var i = 0; i <= 170; i++)
state.lookupFact[i] = fact(i)
return state.lookupFact[par]
// use it like this later on
console.log(lookupFact(1), lookupFact(10), lookupFact(5))
正如我所说,只有当您必须一直计算阶乘时才应该使用它。
【讨论】:
以上是关于使用 .map 分解数组中的所有数字的主要内容,如果未能解决你的问题,请参考以下文章