Since you specifically asked not to convert strings to integers, here is a method that uses only string manipulation function - no parseInt
.
To use it just call incrementString('123')
.
var incrementMapPositive = { '0': '1', '1': '2', '2': '3', '3': '4', '4': '5', '5': '6', '6': '7', '7': '8', '8': '9', '9': '0' };
var incrementMapNegative = { '0': '9', '9': '8', '8': '7', '7': '6', '6': '5', '5': '4', '4': '3', '3': '2', '2': '1', '1': '0' };
function incrementString(str, pos) {
if (!str)
return '';
// handle case '-0'
if (/^-0+$/.test(str))
str = '0';
// position count starts from the end, so get the proper index
var posFromStart = str.length - 1 - (pos || 0);
// get the character to increment (use the last one if none specified)
var chr = str.charAt(posFromStart);
var isNegative = str.charAt(0) === '-';
var incrementMap = isNegative ? incrementMapNegative : incrementMapPositive;
// if the very first digit is carried (e.g. incrementing from 99 to 100), we need to add a '1'
var newChr = !chr ? '1' : incrementMap[chr];
// build the new string with the replaced digit
var incremented = str.substr(0, posFromStart) + newChr + str.substr(posFromStart + 1);
// detect if we need to carry/borrow from the next digit
if (!isNegative && newChr === '0' || isNegative && newChr === '9')
incremented = incrementString(incremented, (pos || 0) + 1);
//clean leading zeros
incremented = incremented.replace(/^(-)?0+/, '$1');
if (incremented === '-')
incremented = '0';
return incremented;
}
EDIT: replaced if-else blocks with a mapping object. Also incrementing correctly negative numbers now.
EDIT 2: made some cleanup and added some inline comments to better explain code.
EDIT 3: handling case '-0'