
Inhalt
Die Fakten:
| Plattform: | codewars.com |
| Name: | String incrementer |
| Level: | 5 kyu |
| Sprache: | JavaScript |
Beschreibung:
Your job is to write a function which increments a string, to create a new string.
- If the string already ends with a number, the number should be incremented by 1.
- If the string does not end with a number. the number 1 should be appended to the new string.
Examples:
foo -> foo1
foobar23 -> foobar24
foo0042 -> foo0043
foo9 -> foo10
foo099 -> foo100
Attention: If the number has leading zeros the amount of digits should be considered.
Quelle: codewars.com
Lösung
Pseudo-Code
Es gibt wie immer viele Varianten, hier ist eine meiner.
Erst die Lösungsschritte in Pseudo-Code. Los geht’s:
Lösungsschritte
Schritt 1
Zuerst brauchen wir den Index des letzten Buchstaben im Input-String. Dafür macht es Sinn sich eine kleine Helferfunktion anzulegen
Schritt 2
In der Helferfunktion loopen wir von Hinten durch alle Zeichen des Input-Strings
Schritt 3
Wenn wir das erste Zeichen finden, das keine Zahl ist, können wir Loop und Funktion (vorzeitig) beenden und das Zeichen zurückgeben
Schritt 4
In der Hauptfunktion suchen wir uns mit Hilfe der Helferfunktion zuerst den letzten Buchstaben im Input-String und bestimmen dann dessen Index
Schritt 5
Mit dem Index des letzten Buchstaben können wir dann den Input-String in 2 Teile schneiden. Den Teil mit der Zahl am Ende und den Teil ohne die Zahl am Ende
Schritt 6
Dann erhöhen wir die Zahl um 1
Schritt 7
Zum Schluss noch die Zahl wieder in einen String umwandeln, etwaige Nullen wieder voranstellen, den Teil ohne die Zahl davor und alles zusammen zurückgeben
Code
Geil. Übersetzen wir unseren Pseudo-Code in JavaScript:
Lösungsschritte
Die erste Zeile meiner Hilfsfunktion (ich habe strng in str umbenannt):
function getLastLetter(str) {
Als Erstes den String umdrehen:
const reversedStr = [...str].reverse();
Damit wir den String reversieren koennen, muessen wir ihn zuerst arrayfizieren. Das machen wir hier mit dem Spread-Operator
in eckigen Klammern.
Dann durch den umgedrehten String loopen:
for (let char of reversedStr) {
Wenn das aktuelle Zeichen keine Zahl ist, geben wir es direkt zurück und beenden Loop und Funktion:
if (!Number.isInteger(Number(char))) return char;
}
}
Das war's schon für's Helferlein. Weiter geht's mit der Hauptfunktion.
Die Erste Zeile meiner Hauptfunktion (ich habe strng in str umbenannt):
function incrementString(str) {
Zuerst holen wir uns mit unserer Hilfsfunktion den letzten Buchstaben im Input-String und bestimmen dann dessen Index:
const lastLetter = getLastLetter(str);
const lastLetterIndex = str.lastIndexOf(lastLetter);
Cool:
Sollte der Input-String keinen Buchstaben enthalten, gibt uns getLastLetter() hier undefined zurück. .lastIndexOf() von undefined wiederum gibt uns -1 zurück. Das wird uns gleich von Nutzen sein...
Dann teilen wir den Input-String in 2 Teile, 1x die Zahlen und 1x den Rest ohne die Zahlen:
const strWithoutTrailingNum = str.slice(0, lastLetterIndex + 1);
const trailingNumStr = str.slice(lastLetterIndex + 1);
Sollte es keinen Buchstaben im String geben, ist lastLetterIndex hier wie oben beschrieben -1. In diesem Fall ist lastLetterIndex + 1 also 0 und strWithoutTrailingNum ein leerer String "". Nice.
Jetzt können wir die Zahl um 1 erhöhen und das Ergebnis wieder in einen String umwandeln:
const newNum = Number(trailingNumStr) + 1;
const newNumStr = newNum.toString().padStart(trailingNumStr.length, "0");
Durch das Umwandeln eines Strings in ein Zahl mit Number() werden voranstehende Nullen entfernt.
Nicht vergessen diese etwaigen fehlenden Nullen wieder vorne dran zu stellen! (z.B. mit padStart())
Zu guter Letzt geben wir nur noch den zusammengesetzten String zurück:
return strWithoutTrailingNum + newNumStr;
}
Sollte wie oben beschrieben kein Buchstabe im Input-String enthalten sein, ist strWithoutTrailingNum ein leerer String "". So geht unsere Funktion auch für diese Fälle wunderbar auf!
Voilá! 💪
Komplettlösung
function incrementString(str) {
const lastLetter = getLastLetter(str);
const lastLetterIndex = str.lastIndexOf(lastLetter);
const strWithoutTrailingNum = str.slice(0, lastLetterIndex + 1);
const trailingNumStr = str.slice(lastLetterIndex + 1);
const newNum = Number(trailingNumStr) + 1;
const newNumStr = newNum.toString().padStart(trailingNumStr.length, "0");
return strWithoutTrailingNum + newNumStr;
}
function getLastLetter(str) {
const reversedStr = [...str].reverse();
for (let char of reversedStr) {
if (!Number.isInteger(Number(char))) return char;
}
}