使用 .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);

【讨论】:

谢谢!我会试试这个。没想到要分开他们:) 这行得通:) 你能解释一下第一行发生的事情吗?将不胜感激 @Tony fact 是一个签名接受参数 (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 + 1n = 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 分解数组中的所有数字的主要内容,如果未能解决你的问题,请参考以下文章

从使用中的数组中添加数字

如何使用字符串数组来分解数字的各个数字?

使用map方法Javascript遍历数组中的所有数组索引

数组中的可观察数组,数字总和?

如何使用 filter()、map() 处理数组的值? JavaScript

#yyds干货盘点#Galang中的map数据类型使用