Javascript - 使用纯递归函数创建具有FizzBu​​zz结果的数组

时间:2021-07-14 16:46:10

I am trying to get a better understanding of recursion and am thus trying create an array with numbers using the common 'Fizzbuzz' problem. I am trying to do this by implementing a pure recursive function with only one input, but I am having trouble getting my answer to appear in the correct order. I was also curious to know if there was a way to write a pure recursive function that would use push instead of concat in this situation. Any help is appreciated! I am able to print out the desired output, but am doing it in reverse order. Below is what I have so far:

我试图更好地理解递归,因此尝试使用常见的'Fizzbuzz'问题创建一个带数字的数组。我试图通过实现一个只有一个输入的纯递归函数来做到这一点,但我无法让我的答案以正确的顺序出现。我也很想知道是否有办法编写一个纯粹的递归函数,在这种情况下使用push而不是concat。任何帮助表示赞赏!我能够打印出所需的输出,但是按相反的顺序进行。以下是我到目前为止:

 var fizzBuzz = function(n) {
    //create results array
    //create base case for when n === 1
    //recurse and push value to array
    var results = [];
  if (n === 1) {
    return '1';
  } else {
    if (n % 3 === 0 && n % 5 === 0) {
      results.push('FizzBuzz');
    } else if (n % 5 === 0) {
      results.push('Buzz');
    } else if (n % 3 === 0) {
      results.push('Fizz');
    } else {
      results.push(''+ n);
    }
    return results.concat(fizzBuzz(n - 1));
  }
};

3 个解决方案

#1


2  

There are many ways to do this and it depends on your requirements.

有很多方法可以做到这一点,这取决于您的要求。

One of the easiest way is to reverse your array in the end:

最简单的方法之一是最终反转你的数组:

function fizzBuzz(n) {
  function fizzBuzzRecursive(n) {
    //create results array
    //create base case for when n === 1
    //recurse and push value to array
    var results = [];
    if (n === 1) {
      return '1';
    } else {
      if (n % 3 === 0 && n % 5 === 0) {
        results.push('FizzBuzz');
      } else if (n % 5 === 0) {
        results.push('Buzz');
      } else if (n % 3 === 0) {
        results.push('Fizz');
      } else {
        results.push(''+ n);
      }
      return results.concat(fizzBuzzRecursive(n - 1));
    }
  }
  
  return fizzBuzzRecursive(n).reverse();
};

console.log(fizzBuzz(15));

It may look ugly but it solves your problem with minimal changes in code (sometimes, it is a key requirement).

它可能看起来很难看,但它解决了你的问题,代码变化很小(有时,这是一个关键要求)。

Another solution is to concat fizzBuzzRecursive to your results instead. Note that in order to make it work you need to return [1] instead of "1" for n == 1, so that JS interprets the first result as an array, not a string.

另一个解决方案是将fizzBu​​zzRecursive连接到您的结果。请注意,为了使其工作,您需要为n == 1返回[1]而不是“1”,以便JS将第一个结果解释为数组,而不是字符串。

function fizzBuzz(n) {
    //create results array
    //create base case for when n === 1
    //recurse and push value to array
    var results = [];
  if (n === 1) {
    return ['1']; // !
  } else {
    if (n % 3 === 0 && n % 5 === 0) {
      results.push('FizzBuzz');
    } else if (n % 5 === 0) {
      results.push('Buzz');
    } else if (n % 3 === 0) {
      results.push('Fizz');
    } else {
      results.push(''+ n);
    }
    return fizzBuzz(n - 1).concat(results);
  }
};

console.log(fizzBuzz(15));

The third solution is to change your recursive function so that it iterates in a reverse order. You may try it yourself :)

第三种解决方案是更改递归函数,使其以相反的顺序迭代。你可以自己试试:)

#2


0  

Another solution which iterates from 0 (kinda): https://repl.it/FysV/1

另一个从0(有点)迭代的解决方案:https://repl.it/FysV/1

var hold = 0;
var fizzBuzz = function(n) {
  var results = [];

  if(hold === n) return '' + n;

  if(hold === 0) {
    hold = n;
    n = 1;
  }

  if (n === 1) {
    results.push('1');
  } else if (n % 3 === 0 && n % 5 === 0) {
    results.push('FizzBuzz');
  } else if (n % 5 === 0) {
    results.push('Buzz');
  } else if (n % 3 === 0) {
    results.push('Fizz');
  } else {
    results.push(''+ n);
  }

  return results.concat(fizzBuzz(n + 1));
}

#3


0  

First approach: passing the array as parametter

第一种方法:将数组作为参数传递

var fizzBuzz = function(n, arr = []) {   // fizzBuzz should have two params: the number n and the accumulated array arr
  
  // if you don't like the arr = [] in the parametter, or if it's not supported then just declare arr as a regular argument (function(n, arr)) and uncomment the following line to check if the array is passed or not (in the first call)
  // arr = arr || [];
  
  if (n === 1) {                         // if n is 1 then add 1 to the array and return its inverse because we didn't fuzzBuzz in the right order
    arr.push('1');
    return arr.reverse();
  } else {                               // logic blah blah ...
    if (n % 3 === 0 && n % 5 === 0) {
      arr.push('FizzBuzz');
    } else if (n % 5 === 0) {
      arr.push('Buzz');
    } else if (n % 3 === 0) {
      arr.push('Fizz');
    } else {
      arr.push('' + n);
    }
    return fizzBuzz(n - 1, arr);         // no need to use concat because we are passing the acummulated array to append to it
  }
}

console.log(fizzBuzz(10));

Second approach: function inside function with clossures

第二种方法:功能内部功能与clossures

var fizzBuzz = function(n) {
  var arr = [];                        // the array
  
  function fizzBuzzInternal(i) {       // the real fizzBuzz function
    if (i % 3 === 0 && i % 5 === 0) {  // logic blah blah ...
      arr.push('FizzBuzz');
    } else if (i % 5 === 0) {
      arr.push('Buzz');
    } else if (i % 3 === 0) {
      arr.push('Fizz');
    } else {
      arr.push('' + i);
    }
    
    if(i < n)                         // if i is still less than n then invoke another fizzBuzzInternal call
      fizzBuzzInternal(i + 1);
  }
  
  fizzBuzzInternal(1);                // invoke the first fizzBuzzInternal to start the show
  
  return arr;                         // return the array (no need for inversing because we fizzBuzzed in the right direction)
}

console.log(fizzBuzz(10));

#1


2  

There are many ways to do this and it depends on your requirements.

有很多方法可以做到这一点,这取决于您的要求。

One of the easiest way is to reverse your array in the end:

最简单的方法之一是最终反转你的数组:

function fizzBuzz(n) {
  function fizzBuzzRecursive(n) {
    //create results array
    //create base case for when n === 1
    //recurse and push value to array
    var results = [];
    if (n === 1) {
      return '1';
    } else {
      if (n % 3 === 0 && n % 5 === 0) {
        results.push('FizzBuzz');
      } else if (n % 5 === 0) {
        results.push('Buzz');
      } else if (n % 3 === 0) {
        results.push('Fizz');
      } else {
        results.push(''+ n);
      }
      return results.concat(fizzBuzzRecursive(n - 1));
    }
  }
  
  return fizzBuzzRecursive(n).reverse();
};

console.log(fizzBuzz(15));

It may look ugly but it solves your problem with minimal changes in code (sometimes, it is a key requirement).

它可能看起来很难看,但它解决了你的问题,代码变化很小(有时,这是一个关键要求)。

Another solution is to concat fizzBuzzRecursive to your results instead. Note that in order to make it work you need to return [1] instead of "1" for n == 1, so that JS interprets the first result as an array, not a string.

另一个解决方案是将fizzBu​​zzRecursive连接到您的结果。请注意,为了使其工作,您需要为n == 1返回[1]而不是“1”,以便JS将第一个结果解释为数组,而不是字符串。

function fizzBuzz(n) {
    //create results array
    //create base case for when n === 1
    //recurse and push value to array
    var results = [];
  if (n === 1) {
    return ['1']; // !
  } else {
    if (n % 3 === 0 && n % 5 === 0) {
      results.push('FizzBuzz');
    } else if (n % 5 === 0) {
      results.push('Buzz');
    } else if (n % 3 === 0) {
      results.push('Fizz');
    } else {
      results.push(''+ n);
    }
    return fizzBuzz(n - 1).concat(results);
  }
};

console.log(fizzBuzz(15));

The third solution is to change your recursive function so that it iterates in a reverse order. You may try it yourself :)

第三种解决方案是更改递归函数,使其以相反的顺序迭代。你可以自己试试:)

#2


0  

Another solution which iterates from 0 (kinda): https://repl.it/FysV/1

另一个从0(有点)迭代的解决方案:https://repl.it/FysV/1

var hold = 0;
var fizzBuzz = function(n) {
  var results = [];

  if(hold === n) return '' + n;

  if(hold === 0) {
    hold = n;
    n = 1;
  }

  if (n === 1) {
    results.push('1');
  } else if (n % 3 === 0 && n % 5 === 0) {
    results.push('FizzBuzz');
  } else if (n % 5 === 0) {
    results.push('Buzz');
  } else if (n % 3 === 0) {
    results.push('Fizz');
  } else {
    results.push(''+ n);
  }

  return results.concat(fizzBuzz(n + 1));
}

#3


0  

First approach: passing the array as parametter

第一种方法:将数组作为参数传递

var fizzBuzz = function(n, arr = []) {   // fizzBuzz should have two params: the number n and the accumulated array arr
  
  // if you don't like the arr = [] in the parametter, or if it's not supported then just declare arr as a regular argument (function(n, arr)) and uncomment the following line to check if the array is passed or not (in the first call)
  // arr = arr || [];
  
  if (n === 1) {                         // if n is 1 then add 1 to the array and return its inverse because we didn't fuzzBuzz in the right order
    arr.push('1');
    return arr.reverse();
  } else {                               // logic blah blah ...
    if (n % 3 === 0 && n % 5 === 0) {
      arr.push('FizzBuzz');
    } else if (n % 5 === 0) {
      arr.push('Buzz');
    } else if (n % 3 === 0) {
      arr.push('Fizz');
    } else {
      arr.push('' + n);
    }
    return fizzBuzz(n - 1, arr);         // no need to use concat because we are passing the acummulated array to append to it
  }
}

console.log(fizzBuzz(10));

Second approach: function inside function with clossures

第二种方法:功能内部功能与clossures

var fizzBuzz = function(n) {
  var arr = [];                        // the array
  
  function fizzBuzzInternal(i) {       // the real fizzBuzz function
    if (i % 3 === 0 && i % 5 === 0) {  // logic blah blah ...
      arr.push('FizzBuzz');
    } else if (i % 5 === 0) {
      arr.push('Buzz');
    } else if (i % 3 === 0) {
      arr.push('Fizz');
    } else {
      arr.push('' + i);
    }
    
    if(i < n)                         // if i is still less than n then invoke another fizzBuzzInternal call
      fizzBuzzInternal(i + 1);
  }
  
  fizzBuzzInternal(1);                // invoke the first fizzBuzzInternal to start the show
  
  return arr;                         // return the array (no need for inversing because we fizzBuzzed in the right direction)
}

console.log(fizzBuzz(10));