0

Hey I am trying to write some code to handle the unformatting of EU and US numbers but I can not get a perfect solution.

For example I would like

1.222.222,89 to be 1222222.89 1,222,222.89 to be 1222222.89

I am using AG GRID and I am pasting numbers to the grid which ag grid is storing as strings.

what I have got so far but will not work with numbers with only a single ',' or '.'

let unformattedNumber = params.value as string;

unformattedNumber = unformattedNumber.replace("%", "");
unformattedNumber = unformattedNumber.replace(/ /g, "");

const lastCommaIndex = unformattedNumber.lastIndexOf(",");
const lastPeriodIndex = unformattedNumber.lastIndexOf(".");

if (lastCommaIndex > lastPeriodIndex) {
  unformattedNumber = unformattedNumber.replace(/\./g, "");
  unformattedNumber = unformattedNumber.replace(",", ".");
} else if (lastPeriodIndex > lastCommaIndex) {
  unformattedNumber = unformattedNumber.replace(/,/g, "");
}

return parseFloat(unformattedNumber);
eamohego
  • 9
  • 4
  • 1
    Does this answer your question? [How can I parse a string with a comma thousand separator to a number?](https://stackoverflow.com/questions/11665884/how-can-i-parse-a-string-with-a-comma-thousand-separator-to-a-number) – evolutionxbox Jul 26 '23 at 13:03
  • 1
    Specifically [this answer](https://stackoverflow.com/a/45309230/989920) – evolutionxbox Jul 26 '23 at 13:03
  • I do not think this works. I am dealing with strings and we are a big company so the idea is that people will share excels with each other and use our app and copy and paste stuff into the grid so they very likely could be looking at a format not in their locale. – eamohego Jul 26 '23 at 13:17
  • That answer still shows how to convert the string into a number – evolutionxbox Jul 26 '23 at 13:20
  • So use one of the other 21 answers... – Heretic Monkey Jul 26 '23 at 13:51
  • @eamohego is it safe to assume that all the numbers will be rounded to just two decimal places? – Izebeafe Jul 26 '23 at 14:03
  • no so this is used in copy and paste to ag grid. so a user might copy a number like 23.3333 to the grid. – eamohego Jul 26 '23 at 14:09
  • This can be tricky if the user doesn't define the format they are using, cause 1,567 can mean 1 with 3 decimal places of '567', and can also mean one-thousand five-hundred and sixty-seven. So the program might not work to full expectation everytime – Izebeafe Jul 26 '23 at 14:20
  • yeah I can get a solution to like 80 percent work but can't find a perfect solution – eamohego Jul 26 '23 at 14:20

3 Answers3

0

Seems like you are on the right track. You can try this out:

function unformatNumber(input: string): number {
  // Step 1: Remove percentage sign '%' and spaces
  let unformattedNumber = input.replace("%", "").replace(/ /g, "");

  // Step 2: Use regex to replace EU/US formats with a consistent format
  unformattedNumber = unformattedNumber.replace(/[,.](?=\d{3})/g, "");
  unformattedNumber = unformattedNumber.replace(",", ".");

  return parseFloat(unformattedNumber);
}

// Test cases
console.log(unformatNumber("1.222.222,89")); // Output: 1222222.89
console.log(unformatNumber("1,222,222.89")); // Output: 1222222.89
console.log(unformatNumber("1,222,222"));    // Output: 1222222
console.log(unformatNumber("1.222.222"));    // Output: 1222222
console.log(unformatNumber("12% 34,56"));    // Output: 1234.56
Abhishek Patel
  • 258
  • 3
  • 10
0

I hope it works how You want it to be! Used JS a long time ago.

function unformatNumber(number) {

  let unformattedNumber = number.replace(/[,]/g, '');
  let lastCommaIndex = number.lastIndexOf(',');
  let amount = number.match(/,/g);
    
  unformattedNumber = unformattedNumber.slice(0, lastCommaIndex- 
  amount.length+1) + '.' + unformattedNumber.slice(lastCommaIndex- 
  amount.length+1, unformattedNumber.length)
 
  return unformattedNumber;
}

let uNumber = "1,222,222,89"; //OUTPUT 1222222.89
console.log(unformatNumber(uNumber));
Piterek237
  • 61
  • 11
  • this doesnt work with EU format – eamohego Jul 26 '23 at 13:34
  • Yes, but works for US so? You can change the code if You have a part of it. It is the same – Piterek237 Jul 26 '23 at 13:38
  • So you output one version, the US centric version, and call it a day? As if the EU's style is invalid or something? What if you don't know which version you are going to get? – somethinghere Jul 26 '23 at 13:40
  • It's just a part of code? It's really simple logic If You have one part you should easly make the second one. If else logic is one of the simplest thing I guess – Piterek237 Jul 26 '23 at 13:41
  • Okay, but that's not being helpful here? "Here half of the answer, any developer should be able to figure out the other half" is not a great attitude for a site where people come to learn from others? – somethinghere Jul 26 '23 at 13:45
  • I did not mean it like that. He should do it himself to learn, cause those are the things that teach You the most. – Piterek237 Jul 26 '23 at 13:50
  • Let him try that individually and then if he have some problems ask them – Piterek237 Jul 26 '23 at 13:50
  • 'if you have one part you should easly make the second one' - so show me :( haha I have been embarrassingly at this all day the problem is edge cases of 1,234 and 1.22 from what I can tell it is difficult to perfectly prepare a function that can handle not knowing which format is coming at it – eamohego Jul 26 '23 at 13:53
  • describe me perfectly what is Your bigest problem here and show me the examples that breakes the code – Piterek237 Jul 26 '23 at 13:57
0

I'm not very good with regex so I used arrays. May not be the best practice, but it works:

function formatNumber(unformattedNumber) {
  const rawNumber = unformattedNumber.split("").filter((char) => {
    return char !== "," && char !== "."
  })
  if (rawNumber.length !== 9) {
    console.log("Wrong number format")
  } else {
    const a = rawNumber.pop()
    const b = rawNumber.pop()
    const formattedNumber = [...rawNumber, ".", a, b].join("")
    console.log(formattedNumber)
  }
}

formatNumber("1.222.222,89")

I tried shortening the .pop() process by just using splice() but for some reason, it wasn't working too well on JSFiddle, here's the code for that if you want it tho:

function formatNumber(unformattedNumber) {
  const rawNumber = unformattedNumber.split("").filter((char) => {
    return char !== "," && char !== "."
  })
  if (rawNumber.length !== 9) {
    console.log("Wrong number format")
  } else {
    const formattedNumber = rawNumber.splice(7, 0, ".").join("")
    console.log(formattedNumber)
  }
}

formatNumber("1.222.222,89")
Izebeafe
  • 182
  • 1
  • 4