This parses two digits and returns the rest of the string.
Input:
"20asg"
Output:
{ number: 20, left: "asg" }
Input:
"9asg"
Output:
{ number: 9, left: "asg" }
function readDigit(str) {
var digitMap = {
0: 0,
1: 1,
2: 2,
3: 3,
4: 4,
5: 5,
6: 6,
7: 7,
8: 8,
9: 9
};
var number1 = digitMap[str[0]];
var number2 = digitMap[str[1]];
if (number2 === undefined) {
if (number1 === undefined) {
return {
left: str.slice(1)
};
}
return {
number: number1,
left: str.slice(1)
};
} else {
return {
number: (number1 * 10) + number2,
left: str.slice(2)
};
}
}
2 Answers 2
This seems like a perfect job for a simple regular expression:
/^(\d+)(.*)$/
That pattern matches a string starting with (^
) one or more digits (\d+
), and whatever comes after it (.*
). The parentheses make the two parts into explicit capture groups.
So you can do this
function readDigit(str) {
var match = str.match(/^(\d+)(.*)$/);
if(!match) {
return { left: str };
}
return {
number: parseInt(match[1], 10),
left: match[2]
};
}
Edit: If you specifically want to find 2 digits (not just 1-or-more), you can use the following pattern instead:
/^(\d\d)(.*)$/
or its equivalent:
/^(\d{2})(.*)$/
-
\$\begingroup\$ This is almost certainly a non-issue but your answer will output
9
for09ahshd
\$\endgroup\$Daniel F– Daniel F2016年03月20日 02:21:57 +00:00Commented Mar 20, 2016 at 2:21 -
\$\begingroup\$ @DanielF So will OP's code. While it doesn't use
parseInt
(though it should), it still maps stringified digits to their numeric values. And the string"09"
thus becomes the number9
. \$\endgroup\$Flambino– Flambino2016年03月20日 02:34:38 +00:00Commented Mar 20, 2016 at 2:34 -
\$\begingroup\$ Thanks. I missed the
(number1 * 10) + number2
and thought they were concating them \$\endgroup\$Daniel F– Daniel F2016年03月20日 04:16:50 +00:00Commented Mar 20, 2016 at 4:16
Instead of looking at the first two characters separately, you can just slice off digits from the beginning of the string until you reach the desired length. That also allows you to check if there are any more characters in the source strings, so that it can handle strings like "a"
, "1"
or even an empty string without crashing.
I assume that the expected result when no digits are found should be the entire string, not the string with the first character sliced off as in the original code. I.e. when input is "asg"
the output would be { left: "asg" }
rather than { left: "sg" }
.
Accessing strings using brackets works in all modern browsers, but you might want to use the charAt
method instead which works on all platforms.
function readDigit(str) {
var n = 0;
while (n < 2 && n < str.length && str.charAt(n) >= '0' && str.charAt(n) <= '9') {
n++;
}
var result = { left: str.substr(n) };
if (n.length) result.number = parseInt(str.substr(0, n), 10);
return result;
}
You can make the function more flexible (reusable) by adding a maxLength
parameter, and use n < maxLength
instead of n < 2
.