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;
}
}