1

I am new to Javascript and am following freecodecamp. As I understand, I think I should be able to multiply a number by i each time it changes in a for loop by the value of i itself. I am doing this because I am trying to factorialize. I sort of peeped at the answer and they used a factorialize type javascript function or something. I'd still like to solve this using my own coding. How would I do this?

Below is the code of what I have already tried.

function factorialize(num) {
  for (let i = 1; i < num; i++) {
   let answer = i * num;
  }
  return answer;
}

If I input 10 for a number I'd like it to take the factorial of 10 (i.e 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1). I would hope this to work for 0 as well somehow, but we can always start with my original question.

Oversought
  • 57
  • 8
  • 3
    Declare `answer` **outside** the loop. – Pointy Apr 23 '19 at 20:46
  • Ah. Care to explain why it needs to be declared outside instead of inside the loop? I'm very new to all of this. Thanks for helping out. – Oversought Apr 23 '19 at 20:52
  • The `let` statement works differently than `var`. In your code the variable is essentially "private" to the loop code block, so invisible outside there. – Pointy Apr 23 '19 at 20:54
  • Could I have used var inside the for loop to get the desired factorializing effect? – Oversought Apr 23 '19 at 20:59

2 Answers2

4

You need to declare and initialize answer before the looping and you need to take i and answer for multiplying.

An while you have already 1 as starting value, you can start the loop from the second value. And you need the last value as well.

Worth a read: What's the difference between using "let" and "var"?

function factorialize(num) {
    let answer = 1;
    for (let i = 2; i <= num; i++) {
        answer = i * answer;
    }
    return answer;
}

console.log(factorialize(5));

A while loop approach

function factorialize(num) {
    var product = 1;
    while (num) product *= num--;
    return product;
}

console.log(factorialize(5));

A recursive approach.

function factorialize(num) {
    return num
        ? num * factorialize(num - 1)
        : 1;
}

console.log(factorialize(5));
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • You're the MVP thank you! Care to explain why this answer needs to be initialized or declared before the for loop/outside of it? Why can't I do what I did? – Oversought Apr 23 '19 at 20:54
  • declaring inside with `let` makes the variable only visible inside of the block and the value can not be changed to hold the product of all values. – Nina Scholz Apr 23 '19 at 21:02
  • By the way this line of logic works really well for me naturally, but I will try to learn the others suggested below, especially the recursive one, as that is how it was solved in the solution on freecodecamp. – Oversought Apr 23 '19 at 21:04
  • Makes sense Nina, thanks. What if I were to use my initial proposed solution but use var instead? – Oversought Apr 23 '19 at 21:05
  • as long as the scope of the variable is outside of the loop, you could take either `let` or `var`. – Nina Scholz Apr 23 '19 at 21:07
  • In the recursive example you added, what's stopping it from taking it times 0, then -1, etc.? It doesn't look like there's something stopping that from happening. – Oversought Apr 23 '19 at 21:19
  • 1
    the zero is stopping the recursion, because of the [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy) nature of this value and the [conditional (ternary) operator `?:`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator) returns `1`. – Nina Scholz Apr 23 '19 at 21:21
1

You can always use a while loop too:

function factorialize(num)
{
    let answer = 1;

    while (num > 0)
    {
       answer = answer * num;
       num--;
    }

    return answer;
}

console.log("Result for 0:", factorialize(0));
console.log("Result for 5:", factorialize(5));
console.log("Result for 10:", factorialize(10));
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

Or go the recursive way:

const factorialize = (num) => num <= 0 ? 1 : num * factorialize(num - 1);

console.log("Result for 0:", factorialize(0));
console.log("Result for 5:", factorialize(5));
console.log("Result for 10:", factorialize(10));
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}
Shidersz
  • 16,846
  • 2
  • 23
  • 48
  • I really like the recursive solution because it seems to be short and sweet, especially with the ternary operator. Care to explain why the else return "num * factorialize(num - 1);" would actually return a factorial of num? – Oversought Apr 23 '19 at 21:09
  • @Oversought what is `5 * 4!`? It's `5!`. – Pointy Apr 23 '19 at 21:10
  • Oh so calling the function back at the end of the ternary inside the function itself is why it keeps repeating recursively. I was confused as to how that happened. I understand how factorials work, just didn't know exactly how that coding did that. I think I understand it better now though. – Oversought Apr 23 '19 at 21:13
  • 1
    @Oversought Sure, I will try with a basic example. Suppose we call `factorialize(3)`, then we get `3 * factorialize(2)` in the first call. Now, that expression will be reduced to `3 * (2 * factorialize(1))` and so on, until we get `3 * (2 * (1 * (1 /*this is returned by factorialize(0)*/)))`. Note also, accepted answer should be that of **@Nina Scholz** since it explains your original problem. I was just trying to offer some alternatives. – Shidersz Apr 23 '19 at 21:21
  • I definitely appreciate alternatives. This is off-topic, but once I know all of these languages that I wish to learn (as many as possible), will I have to go back to school to get some credentials in CS/ or w/e or can I shoe my way into a career of this somehow? I've had issues with health/debt so it isn't easy to go back to school. – Oversought Apr 23 '19 at 21:30