1

I am a beginner in javascript and I try to write a simple decoding function. Here it is:

function decode(text) {
let letter, count, i, result, letters;
result = "";
for (i = 0; i < text.length; i++) {
        count = text[i];
        if (typeof Number(count) === "number") {               
            count = Number(count);
            console.log(count);  // this line only for testing
            letter = text[i + 1];
            letters = letter.repeat(count);
            result += letters;
            console.log(result);  // this line only for testing
        } else {
            result += text[i];
        }
    }
    return result;
}
console.log(decode("v2rt3b2x"));

I need help in understanding why the if clause is not being skipped when typeof Number(count) === "number" is false. It returns this:

NaN
VM708:12 
VM708:8 2
VM708:12 rr
VM708:8 NaN
VM708:12 rr
VM708:8 NaN
VM708:12 rr
VM708:8 3
VM708:12 rrbbb
VM708:8 NaN
VM708:12 rrbbb
VM708:8 2
VM708:12 rrbbbxx
VM708:8 NaN

As I said, I am a beginner, so please be mercifull...

I got the right answer, but I will try to figure out later why count - 1 works, for now I thank everybody for their help.

function decode(text) {
let letter, count, i, result, letters;
result = "";
for (i = 0; i < text.length; i++) {
    count = parseInt(text[i]);
    if (!isNaN(count)) {               
        //console.log(count);  // this line only for testing
        letter = text[i + 1];
        letters = letter.repeat(count-1);
        //console.log(letters);
        result += letters;
        //console.log(result);  // this line only for testing
    } else {
        result += text[i];
    }
}
return result;
}
console.log(decode("v2rt3b2xz3f2d 2s2 j"));
vrrtbbbxxzfffdd ss  j
3
  • 1
    typeof Number(n) always return number. Try using if (typeof count === "number") insted of if (typeof Number(count) === "number"). Commented Sep 30, 2018 at 9:08
  • Thank you very much, but typeof count === "string" Commented Sep 30, 2018 at 9:11
  • 1
    If you want to check whether a character (from your string) is a digit, check this question out. Commented Sep 30, 2018 at 9:12

3 Answers 3

3

typeof Number(x) will always be 'number' no matter what x is. You are literally casting whatever x is to a 'number' type.

So the if clause is always true and never gets skipped.

Sign up to request clarification or add additional context in comments.

Comments

3

The problem is located here.

typeof Number(count) === "number"

When you try to cast something to number, if it is not possible you will get NaN as the value. And typeof NaN is number.

Read more about NaN

Adding Number.isNaN check to your if statement will be the solution.

function decode(text) {
let letter, count, i, result, letters;
result = "";
for (i = 0; i < text.length; i++) {
        count = text[i];
        var parsedNumber = Number(count);
        if (!Number.isNaN(parsedNumber)) {               
            letter = text[i + 1];
            letters = letter.repeat(parsedNumber);
            result += letters;
            console.log(result);  // this line only for testing
        } else {
            result += text[i];
        }
    }
    return result;
}
console.log(decode("v2rt3b2x"));

5 Comments

This is not how Number.isNaN works. It will always return false here. It returns only true when the actual value is NaN (the special value of type Number). You want isNaN (the "default" one) instead, ideally after using parseInt on it, otherwise it will also consider the space character a number.
Thank you, I am working on this and I see that I get closer to getting the right result
@Jeto Well I don't think so. If you look at the implementation of isNaN, It just returns if the value can be converted to a number. But` Number.isNaN` returns whether the given value is NaN. So, I don't think that we will need isNaN for the value we already tried to convert number using Number(count)
@AhmetCanGüven You have edited your code, using Number.isNaN on parsedNumber is better, but it will still fail for spaces as Number(' ') will return 0, which is a digit. This thread pretty much answers this question.
@Jeto Ok I see now, I forgot to use parsedNumber and used count. You were right in that case.
2

Beside the wrong comparison, you could use an approapriate splitting of the string and map the repeated characters.

By taking

'v2rt3b23x'

and splitting

[
    "v2",
    "r",
    "t3",
    "b23",
    "x"
]

and mapping

[
    "vv",
    "r",
    "ttt",
    "bbbbbbbbbbbbbbbbbbbbbbb",
    "x"
]

you get with join

'vvrtttbbbbbbbbbbbbbbbbbbbbbbbx'

console.log(
    'v2rt3b23x'
        .split(/(?=\D)/)
        .map(v => v[0].repeat(v.slice(1) || 1))
        .join('')
);

1 Comment

Thank you very much

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.