Cut unnecessary zeros from a string, without toFixed()

Asked

Viewed 199 times

2

How do I delete zero values from a string? Examples:

"100,50" >> "100,5"
"2,00" >> "2"

Only in cases where there is zero at the end. For example, I do not want to round with that toFixed(1), because it would compromise cases of type "100.56" >> "100.6".

Complementing the situation of my problem:

I’m using a framework to validate some data from a system, and ai has a method to compare the property of an object, and all object properties are strings.

For example the VALUE property is the value that is in the system object and has the value "100.5". And "100.50" is what is in a database. Note that the two are strings, both the system and the database. Then I realized that this giving error with cases of type "100,50" and "2,00".

Ai use the method so: compare(objeto,propriedade, cmp, "100,50"), where the property is the field that has the "100.5".

  • 1

    new Number("100.50") or parseFloat('100.50') or "100.50".replace(/(?:,?0+)$/g, '')

  • 1

    Why are the values comma? Do they possibly not start with dot? Something like 100.5 ? Is the way you approached not trying to solve a problem that maybe shouldn’t even exist?

3 answers

3


If your value is already in the string type, you can use a regular expression like this:

/(^0+(?=\d))|(,?0+$)/g

Which will remove all zeros at the end of a string and the comma if necessary.

Behold:

function stripZeros(str) {
  return str.replace(/(^0+(?=\d))|(,?0+$)/g, '');
}

console.log(stripZeros('100,50')); // 100,5
console.log(stripZeros('2,00')); // 2
console.log(stripZeros('001,00')); // 1
console.log(stripZeros('00,10')); // 0,1

Another option is to convert the string to the type number, which removes the unnecessary zeros and finally converts it back to the desired format:

function stripZeros(str) {
  return parseFloat(str.replace(',', '.'))
    .toString()
    .replace('.', ',');
}

console.log(stripZeros('100,50')); // 100,5
console.log(stripZeros('2,00')); // 2
console.log(stripZeros('001,00')); // 1
console.log(stripZeros('00,10')); // 0,1

  • 2

    work like a Charm, thanks

  • Seeing several cases I imagined that would only leave with regular expression because it is string. But I found only to cut the front zeros. Declaring as a number and then converting to string (https://stackoverflow.com/a/3613112/9585539) would not solve either for my case.

  • @anijahzarri It is not just because it is string that the only solution is a regex. I left a reply without regex for you to see that there are other options :-)

1

There is another option, no regex.

First you need to turn the string into number. Unfortunately parseFloat only accepts the point as decimal separator, so there’s not much to escape from a replace to exchange a comma for a period.

Then, it was not clear how many decimal places they can have in the string (it is always two, can there be another amount? ), then we can use a little "trick" (actually nothing else is that the good old math) to leave the number to only 2 decimal places, without rounding. To do this, simply multiply the number by 100, round down and then divide by 100 again - more generally, for a quantity x of houses, just do these calculations with 10x (but if strings always come with 2 houses, this step is not necessary).

Finally, to format the number, we use toLocaleString, just choose a locale suitable (which in turn controls some aspects, such as the character used as decimal separator), in addition to the number of decimals to be displayed. Would look like this:

function arredonda(s, maxCasas) {
    let n = parseFloat(s.replace(',', '.'));

    // deixar o número com apenas 'maxCasas' casas decimais, sem arredondar
    let fator = Math.pow(10, maxCasas);
    n = Math.floor(n * fator) / fator;

    let opcoes = {
        minimumFractionDigits: 0,
        maximumFractionDigits: maxCasas,
        useGrouping: false
    };
    return n.toLocaleString('pt-BR', opcoes );
}

for (const n of [ '2,00', '100,50', '3', '12,347', '12345,6789' ])
    console.log(`${n} => ${arredonda(n, 2)}`);

The exit is:

2,00 => 2
100,50 => 100,5
3 => 3
12,347 => 12,34
12345,6789 => 12345,67

The option useGrouping: false (described here) causes thousands separator not to be used (its value default is true, then if it is omitted, the last number would be displayed as 12.345,67).

I used the locale pt-BR (Brazilian Portuguese), which uses the comma as decimal separator. Thus, the formatting is already done with the correct character (if you use another locale, as an example en-US (American English), will be used the point instead of the comma). And the other options control the number of decimals to be displayed (using minimum zero and maximum maxCasas, decimals are not displayed when the number does not have the decimal part, for example).

As already said, if all strings always have 2 decimal places, no rounding is necessary, just call toLocaleString shortly after the parseFloat.


If you are working with monetary values, it is interesting to read here.

And if you just want to compare the strings "100.50" and "100.5" based on their numerical values, you didn’t even need to generate the final string, just turn both into numbers (doing the parseFloat with replace) and then compare them.

-1

I also added how to remove zeros before and after the comma of a number in string format:

function stripZeros(str) {
  str = str.replace(/^0+(?=\d)/, '') //remove zeros da frente
  return str.replace(/,?0+$/,''); //remove zeros atras
}

console.log(stripZeros('100,50')); // 100,5
console.log(stripZeros('2,00')); // 2
console.log(stripZeros('001,00')); // 1
console.log(stripZeros('00,10')); // 0,1

Browser other questions tagged

You are not signed in. Login or sign up in order to post.