Konvertiere formatierten STRING to NUMBER
Bello
- javascript
Ok, diese Frage wirkt vielleicht dämlich, aber wie konvertiere ich eine in ein gewisses Format gebrachte Zahl wieder zurück?
Eine number
in ein gewisses Format zu konvertieren ist ziemlich straightforward, 1223432.09 kann ich mit Intl.NumberFormat
alles mögliche antun. Wenn ich jetzt zu einem späteren Zeitpunkt diese zum String
konvertierte Number
zur weiteren Bearbeitung aus dem DOM pflücken möchte, um weitere Kalkulationen anzustellen, so scheint das ohne Androhung von Gewalt nicht ohne weiteres möglich:
const waehrung = "1,223,432.09"
console.log(Number("1,223,432.09")); // NaN
console.log(parseFloat(waehrung)); // 1
console.log(parseInt(waehrung)); // 1
console.log(+waehrung); // NaN
console.log(~~waehrung); // 0
const waehrungToNumber = new Intl.NumberFormat("en-GB", { style: "number", useGrouping: false}).format(waehrung);
console.log(waehrungToNumber); // Uncaught RangeError: invalid value "number" for option style
// ok, bei waehrungToNumber werfe ich dann schon alles [un]mögliche in Richtung Computer... 😈🥴
Muss ich const waehrung
tatsächlich manuell in ein Array zerpflücken und dann wieder zusammensetzen oder übersehe ich eine professionelle Methode?
Danke,
Bello, der mit dem o (am Ende!).
@@Bello
Wenn ich jetzt zu einem späteren Zeitpunkt diese zum
String
konvertierteNumber
zur weiteren Bearbeitung aus dem DOM pflücken möchte, um weitere Kalkulationen anzustellen
Hier liegt der Fehler. Die formatierte Ausgabe des Werts ist nur für die Ausgabe, nicht für weitere Berechnungen.
Für weitere Berechnungen musst du dir den numerischen Wert (den unformatierten) aufheben.
😷 LLAP
Hallo Gunnar,
Wenn ich jetzt zu einem späteren Zeitpunkt diese zum
String
konvertierteNumber
zur weiteren Bearbeitung aus dem DOM pflücken möchte, um weitere Kalkulationen anzustellenHier liegt der Fehler. Die formatierte Ausgabe des Werts ist nur für die Ausgabe, nicht für weitere Berechnungen.
ja, das ist so. Punkt.
Für weitere Berechnungen musst du dir den numerischen Wert (den unformatierten) aufheben.
Es sei denn ... Es sei denn, es geht primär um die Eingabe eines Zahlenwerts, und der formatierte String ist nur der anwender-augenfreundlich hergerichtete Defaultwert, der als Eingabe vorgeschlagen wird.
Dann sind wir aber in einer ganz anderen Liga. Dann geht es darum, Benutzereingaben als Zahlenwert zu interpretieren. Und das ist alles andere als trivial: Verwendet der Nutzer einen Punkt oder ein Komma als Dezimaltrennzeichen? Verwendet er irgendein Zeichen zur Zifferngruppierung? Wenn ja, welches? Punkt, Komma, Leerzeichen? Oder, wie teilweise in der Schweiz üblich, ein Apostroph?
Eine solche Eingabe halbwegs treffsicher zu interpretieren, ist verdammt knifflig. Man kann das mit einem heuristischen Ansatz angehen, aber 100% Trefferquote wird man auch damit nie erreichen.
Ich habe vor einiger Zeit in einer Windows-Applikation eine Funktion in C entworfen, die eine Zeitspanne als Eingabe interpretieren sollte. Dabei sollte HH:MM:SS[.mmm] (mit mmm als Bruchteile von Sekunden, optional) ebenso akzeptiert werden wie SSSS[.mmm] oder HH:MM. Problem: Enthält die Eingabe nur einen Doppelpunkt, aber keinen Punkt, der die Sekundenbruchteile abtrennt, dann ist nicht klar, ob die Eingabe als Stunden:Minuten oder Minuten:Sekunden gmeeint ist. Ich habe mich dann für letzteres entschieden, weil Testläufe über mehrere Stunden eher selten sind, und mich gefreut, als ein Kollege mich irgendwann fragte, wie ich es geschafft hätte, dass das Programm die Eingabe immer so "versteht", wie er sie auch gemeint hatte.
Immer eine Handbreit Wasser unterm Kiel
Martin
Hallo Bello,
die beste Methode ist, wie Gunnar schon schrieb, das separate Aufbewahren des numerischen Wertes. Wenn man eine App im Browser programmiert, sollte man ein fachliches Datenmodell haben und darin operieren, und die Übertragung ins DOM nur als Ausgabeschritt vorsehen, nicht zum Speichern.
Die zweitbeste Methode wäre, den numerischen Wert in einem eigenen Property an das DOM Element zu hängen. Das ist etwas frickelig, weil Du ja kein Recht auf reservierte Eigenschaftsnamen hast. Ein data-Attribut (über die dataset-Eigenschaft eines Elements erreichbar), speichert nur Strings. Du könntest (aber solltest nicht) Dir so helfen, dass Du im dataset den Wert in einem "genormten" Format ablegst, bei dem Du weißt, dass es einen DezimalPUNKT und keine Tausendertrenner gibt. Dann funktioniret parseFloat.
Was sehr unsicher ist bzw. Kenntnis über die bei NumberFormat verwendeten Locales voraussetzt, ist das Entfernen der Tausendergruppierung und das Umsetzen des Dezimaltrennzeichens in einen Punkt.
Angenommen, in in s steht die formatierte Zahl.
Wenn Du weißt, dass das Format en-GB ist:
z = parseFloat(s.replaceAll(",",""));
Wenn Du weißt, dass das Format de-DE ist:
z = parseFloat(s.replaceAll(".","").replace(",","."));
Weitere Formate bedingen andere Ersetzungen. Dazu schrieb Martin schon.
Was leider nicht existiert, ist eine "parse" Methode am NumberFormat, die eine Zahl in dem Format entgegennimmt, in dem format() sie erzeugen würde, und einen float daraus macht. Aus gutem Grund. Ohne Kenntnis der verwendeten Formatierungsregeln ist das reines Raten.
Rolf
@@Rolf B
Ein data-Attribut (über die dataset-Eigenschaft eines Elements erreichbar)
😷 LLAP
Hallo Gunnar,
welches Rahmenwerk tut denn sowas? Das macht ja nicht einmal jQuery…
One Does Not Simply... invent a new one does not simply meme.
Rolf