Aadit M Shah
Aadit M Shah

Reputation: 74234

Why does this incorrect JavaScript program produce the correct answer?

I was given the following JavaScript program in an interview.

const average = xs => {
    let sum = 0;
    for (let num in xs) sum += num;
    return sum / xs.length;
};

const result = average([2, 4, 6]);

console.log(result); // 4

The interviewer told me to explain how this code works. I thought that the average function simply adds all the numbers in the array and divides the sum by the length of the array. However, this wasn't the correct explanation.

There's a bug in the above code. Nevertheless, it produces the correct answer. Can you find the bug and fix it? In addition, can you explain why the above code produces the correct answer even though it is incorrect?

Upvotes: 4

Views: 64

Answers (2)

kooskoos
kooskoos

Reputation: 4869

for... in used for getting keys in an object. As an array is a special implementation of object having keys as a numerical indices, for...in returns these keys.

keys as '0','1','2'

After each iteration string concatenation takes place "0" + "0" + "1" + "2" sum = "0012"

When you try to divide this it is converted to number implicitly 12/3=4

So the output comes out as 4.

You can view this in the following code snippet

let xs = [2,4,6], sum=0 
for (let num in xs) { sum += num; console.log(num,sum); }

Upvotes: 1

Aadit M Shah
Aadit M Shah

Reputation: 74234

The problem is that you're using a for...in loop instead of a for...of loop. A for...of loop would iterate over the array elements, and produce the right answer regardless of input. However, a for...in loop iterates over the array indices. Hence, it would produce the wrong answer in most cases. Nevertheless, for this particular input it produces the right answer.

|  sum   | num |
| ------ | --- |
|  0     | "0" |
| "00"   | "1" |
| "001"  | "2" |
| "0012" |     |

The indices of the array are "0", "1", and "2". The indices are strings, not numbers. Hence, when you add the index "0" to the initial value of sum, i.e. 0, then JavaScript converts the sum into a string, concatenates the two strings, and stores the concatenated string back into sum. At the end of the loop the value of sum is "0012" instead of the expected value 12.

However, both "0012" / 3 and 12 / 3 produce the right answer, i.e. 4. In the first case, JavaScript first converts the string "0012" into the number 12. Hence, we accidentally get the correct answer for this particular input.

Upvotes: 7

Related Questions