【问题标题】:Understanding another Javascript snippet which add digits of a number了解另一个添加数字的 Javascript 片段
【发布时间】:2017-06-11 02:55:19
【问题描述】:

虽然这个问题的答案here 是由于递归方面的最佳答案,

function sumDigits(number) {
    var remainder = number % 10;
    var sum = remainder;
    if(number >= 10) {
        var rest = Math.floor(number / 10);
        sum += sumDigits(rest); 
    }
    return sum;
}

还有另一个似乎更容易理解的答案。但是,答案的某些部分我不明白。

function sumDigits(number) {
  var sum = 0;
  var numbers = number.toString().split(""); //turn the number to string and split the number in several digits

  while(numbers.length > 0) {
    sum += parseInt(numbers[0], 10);  // covert string to number and force the number to be decimal and add the next number 
    numbers.splice(0, 1);  //remove the first digit, in other words, removing "0" from sum, i think?
    sumDigits(numbers.join('')); //join the array element into a string
  }

  return sum;
}

var sum = sumDigits(175);
$('#result').html(sum);

这是我能理解的:

var numbers = number.toString().split("");

将数字转换为字符串并将字符串拆分为子字符串数组。也就是说,如果数字为175,则将其转换为“175”,拆分为1、7、5。接下来,

while(numbers.length > 0) {

这确保数字是正数并且可以添加。但是,当我删除此行并在 JS Bin 中使用负数运行它时,它会返回错误。所以不知何故,重要的是只总结正数。接下来,

sum += parseInt(numbers[0], 10);

这(parseInt)将字符串或在我们的例子中的子字符串转换回数字并将每个数字添加到自身。但是我不明白 numbers 后面括号中的“0”,除非它指的是数组中的第一个数字 = [1, 7, 5]??不过,我可以看到,当我从这一行中删除 [0] 时,它会返回一个错误。另外,加上“sum +=”,应该像这样加起来 0 + 1 + 7 + 5。因此总和是 13。接下来,

numbers.splice(0, 1);

这是我不明白的部分。我知道 .splice 可以添加或删除项目。比如(0,1)的第一部分,也就是“0”,求数组的位置,也就是说,“0”求数组中“1”之前的第一个位置 = [1, 7 , 5]。最后一部分是“1”,指定要删除的项目数量。换句话说,它要求从数组中删除“1”,导致现在数组为 [7, 5]。但是,我认为根本不需要它,因为不需要从数字中删除任何数字。另外,我不明白评论说当总和应该是 13 时,这一行从总和中删除“0”?接下来,

sumDigits(numbers.join(''));

这应该将数组元素连接成一个字符串。换句话说,它应该将array = [1, 7, 5] 加入“1, 7, 5”。不过,我不明白为什么当这行 (sum += parseInt(numbers[0])) 将字符串转换回数字并将数字相加时需要这两行(.splice 和 .join)。但是,当我确实删除了这两行时,该功能不起作用...

请帮助我了解它是如何工作的,哪个是先执行的等等......

【问题讨论】:

  • 为什么不把一对console.logs 放在那里,自己看看它在做什么?

标签: javascript arrays string


【解决方案1】:
 function addDigits(n) {
   let str = n.toString().split('');
   let len = str.length;
   let add,
       acc = 0; 
 for (i=0; i<=len-1; i++) {
   acc += Number(str[i]); 
 } 
 return acc;     
 }
 console.log( addDigits(123456789) );   //Output: 45

【讨论】:

    【解决方案2】:

    哇,这个反应很聪明!我将尝试解释它: 假设我们有那个字符串“3432”

    第一次运行函数时,我们将它拆分:

    numbers = ['3','4','3','2']
    

    那么在这个循环中,我们将做这个过程中最微妙的部分,让我们看看:

    while(numbers.length > 0) { //actually the condition here is number array has to have at least 1 element, we'll see why
        sum += parseInt(numbers[0], 10);  // covert string to number and force the number to be decimal and add the next number 
       //so sum = 0+3 
        numbers.splice(0, 1);  //remove the first digit, in other words, removing "0" from sum, i think?
        //then here you're right, we remove the first digit so that
        number = ['4','3','2']
        sumDigits(numbers.join('')); //join the array element into a string
        //and here we call recursively sumDigits passing "432" in arguments
        /* so next time sum = 3+4, number = ['3','2'] and then 
     we will call sumDigits again with "32" as arguments 
    and then sum = 7+3, number = ['2'], and then 
     we will call sumDigits again with "2" as arguments
    and then sum = 10+2 and number = [] and then we will call sumDigits again passing it "" and at that time the while loop break */
    
      }
    

    【讨论】:

    • 所以这是另一个递归函数,对吗?换句话说,一遍又一遍地重复这些步骤,直到数组中没有项目。
    • 该死!我又意识到了一件事! parseInt 只返回字符串的第一个数字!!!所以需要用.splice来去掉第一个数字!
    • 发布此问题后,我在学习时发现了一种更短的方法。在学习时,我遇到了 .reduce() 方法,它可以获取数组中数字的总和。因此,为了使用 .reduce 方法,必须首先使用 .toString().split("") 返回一个数组 = ["3","4","3","2"]。然后使用 .reduce() 方法。最后,需要将 .Number() 方法应用于 total 和 currentValue 以将“3”转换为 3。示例如下:codepen.io/kikibres/pen/BpdXXq
    【解决方案3】:

    你说得差不多了。

    使用的基本算法是

    1. 将数字转换为字符串number.toString(),并将此字符串拆分为字符数组number.toString().split(""),每个字符代表原始数字的一位

      var numbers = number.toString().split("");
      
    2. 虽然结果数组包含多个零个元素

      while(numbers.length > 0) {
      
    3. 将数组numbers[0]的第一个元素转换为数字parseInt(numbers[0], 10)并添加到sum

      sum += parseInt(numbers[0], 10);
      
    4. 从numbers中删除第一个元素

      numbers.splice(0, 1);
      
    5. 返回 2。如果还有任何元素,则使用较短的数组 numbers 重复。请注意,之前的第二个元素现在是第一个元素

    6. 一旦numbers 的元素为零,则返回sum


    这一步似乎完全没用,应该去掉:

    sumDigits(numbers.join(''));
    

    【讨论】:

    • 完全没有必要将字符串分割成一个字符数组,因为 JavaScript 有一个完美的 String.prototype.slice 函数。我认为该代码的作者想多了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-30
    • 1970-01-01
    • 1970-01-01
    • 2014-01-20
    相关资源
    最近更新 更多