Codewars Lösung | String incrementer


coden
Codewars. Achieve mastery through challenge.
Daniel Kaser|8. August 2024
4 min.

Inhalt

  1. Die Fakten
  2. Beschreibung
  3. Lösung
    1. Pseudo-Code
    2. Code
  4. Feedback

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á! 💪

Fragen?

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

Feedback

Schreib mir!