Code Review Stack Exchange is a question and answer site for peer programmer code reviews. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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)
    };
  }
}
share|improve this question
up vote 6 down vote accepted

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})(.*)$/
share|improve this answer
    
This is almost certainly a non-issue but your answer will output 9 for 09ahshd – Daniel F Mar 20 at 2:21
    
@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 number 9. – Flambino Mar 20 at 2:34
    
Thanks. I missed the (number1 * 10) + number2 and thought they were concating them – Daniel F Mar 20 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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.