Hello
nice solution but due to compatibility of fromatToParts! what do you think about the following class
class UniParser {
constructor(local) {
this._decimal = new Intl.NumberFormat(local, { useGrouping: false }).format(9.9).charAt(1);
this._numerals = new Intl.NumberFormat(local, { useGrouping: false }).format(9876543210).split('').reverse();
this._regx = new RegExp('[' + this._numerals + ']', "g");
}
parse(string) {
let self = this;
return Number(string.replace(this._regx, function (match) {
return self._numerals.indexOf(match);
}).replace(self._decimal, '.'));
}
}
If it works for you, then great! The ideas presented in this notebook are just a sketch (a hack), trying to adapt Intl.NumberFormat to support localized parsing. As I mentioned, this makes a number of assumptions and almost certainly doesn’t generalize to all locales, but maybe it’s better than nothing?
There is a bug in here when the group token is whitespace.
Repro test case: numberParser('fr-CA', '1 999,99'); // returns NaN
This is because _group Regexp is constructed as /[ ]/, and what we really want in this case is probably /[\s]/
Here is my fix:
// modified slightly from his observable. because the group separator doesn't handle whitespace.
// e.g., numberParser('fr-CA', '1 999,99') // returns NaN
// this is because the group regex is generated as /[ ]/ when we really want /[\s]/
const groupVal = parts.find(d => d.type === 'group').value;
const isWhiteSpace = /\s/.test(
typeof groupVal === 'number' ? String.fromCodePoint(groupVal) : groupVal.charAt(0)
)
const _group = new RegExp(`[${isWhiteSpace ? '\\s' : groupVal}]`, 'g');