Nesh
Nesh

Reputation: 2561

Addition of number string in javascript with leading zeros

Following is my code, which is working fine in most scenarios except in case of leading Zeros. It should preserve trailing zeros like -001 + 1 = 002

Code -

function incrementString (str) {
  if(str === '') return "1";
  
  if(!str.slice(-1).match(/\d/)) return `${str}1`;
  
  const replacer = x => {
    // Check if number 
    return (parseInt(x) + 1).toString();
  }
  
  return str.replace(/\d+/g, replacer )
}

// Return foobar2 which is correct
console.log(incrementString("foobar1"))

// Return foobar100 which is correct
console.log(incrementString("foobar099"))

// Return foobar2 which is incorrect, is should be foobar002
console.log(incrementString("foobar001"))

// Return foobar1 which is incorrect, is should be foobar001
console.log(incrementString("foobar000"))

// Return foobar101 which is incorrect, is should be foobar0101
console.log(incrementString("foobar0100"))

Upvotes: 1

Views: 103

Answers (4)

Peter Seliger
Peter Seliger

Reputation: 13417

function incrementString (str) {
  let [
    openingPartial,
    terminatingInt
  ] = str.split(/(\d*)$/);

  if (terminatingInt) {
    const incrementedInt = String(parseInt(terminatingInt, 10) + 1);
    const leadingZeroCount = (terminatingInt.length - incrementedInt.length);

    if (leadingZeroCount >= 1) {

      terminatingInt = Array(leadingZeroCount).fill("0").concat(incrementedInt).join('');
    } else {
      terminatingInt = incrementedInt;
    }
  } else {
    terminatingInt = '1';
  }
  return `${ (openingPartial || '') }${ terminatingInt }`;
}

// Should return 'foo_003_bar1'.
console.log(incrementString("foo_003_bar"));

// Should return 'foo_003_bar_01'.
console.log(incrementString("foo_003_bar_00"));

// Should return 'foobar1'.
console.log(incrementString("foobar"));

// Should return 'foobar2'.
console.log(incrementString("foobar1"));

// Should return 'foobar100'.
console.log(incrementString("foobar099"));

// Should return 'foobar002'.
console.log(incrementString("foobar001"));

// Should return 'foobar001'.
console.log(incrementString("foobar000"));

// Should return 'foobar0101'.
console.log(incrementString("foobar0100"));
.as-console-wrapper { max-height: 100%!important; top: 0; }

Upvotes: 1

SLePort
SLePort

Reputation: 15471

You could split your string from digits and use padStart after increment to preserve leading 0:

const incrementString = (str) => {
  const [chars, nums] = str.split(/(\d+)/)

  return [
    ...chars, 
    String(Number(nums) + 1)
    .padStart(nums.length, '0')
  ].join('')
}

console.log(incrementString("foobar1"))

console.log(incrementString("foobar099"))

console.log(incrementString("foobar001"))

console.log(incrementString("foobar000"))

console.log(incrementString("foobar0100"))

Upvotes: 1

anubhava
anubhava

Reputation: 786291

You may use this regex soluton:

function incrementString (str) {
  if(str === '') return "1";
  
  if(!str.slice(-1).match(/\d/)) return `${str}1`;
  
  const replacer = (m, g1, g2) => {
    // Check if number 
    var nn = (g1?g1:"") + (parseInt(g2) + 1).toString()
    return nn.slice(-1 * m.length)

  }
  
  return str.replace(/(0*)(\d+)/g, replacer )
}

// Return foobar2
console.log(incrementString("foobar1"))

// Return foobar100
console.log(incrementString("foobar099"))

// Return foobar002
console.log(incrementString("foobar001"))

// Return foobar001
console.log(incrementString("foobar000"))

// Return foobar0101
console.log(incrementString("foobar0100"))

// Return foobar01000
console.log(incrementString("foobar00999"))

// Return foobar010
console.log(incrementString("foobar009"))

Upvotes: 2

Aman
Aman

Reputation: 868

Everything seems to be perfect, you need to only handle the regex part of the leading zeroes in your replacer function.Below is the updated code for the same.

function incrementString(str) {
  if (str === '')
    return "1";

  if (!str.slice(-1).match(/\d/)) {
    return `${str}1`;
  }

  const replacer = x => {
    var leadingZerosMatched = x.match(/^0+/);
    var incrementedNumber = (parseInt(x) + 1).toString();
    var leadingZeroes;
    if (leadingZerosMatched && incrementedNumber.length < x.length) {
      leadingZeroes = leadingZerosMatched[0];
      if(leadingZeroes.length === x.length) {
        leadingZeroes = leadingZeroes.slice(0, leadingZeroes.length-1)
      }
    }
    return leadingZeroes ? leadingZeroes + incrementedNumber : incrementedNumber;
  }
  return str.replace(/\d+/g, replacer)
}

Upvotes: 1

Related Questions