Codewars Lösung | Format phone number by template


coden
Codewars. Achieve mastery through challenge.
Daniel Kaser|15. April 2024
3 min.

Inhalt

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

Die Fakten:

Plattform:codewars.com
Name:Format phone number by template
Level:6 kyu
Sprache:TypeScript

Beschreibung:

Introduction

You need to write a function that will format a phone number by a template.

Task

You're given number and string.

If there are more digits than needed, they should be ignored

if there are less digits than needed, should return Invalid phone number

Examples

(79052479075, "+# ### ### ## ##") => "+7 905 247 90 75"
(79052479075, "+# (###) ### ##-##") => "+7 (905) 247 90-75"
(79052479075, "+# ### ### ## ##") => "+7 905 247 90 75"
(81237068908090, "+## ### ### ## ##") => "+81 237 068 90 80"
(8123706890, "+## ### ### ##-##") => "Invalid phone number"
(911, "###") => "911"
(112, "+ () -") => "+ () -"

Check 'Format phone number' series:

Format phone number by template

Format phone number - Mobile App

Quelle: codewars.com

Lösung

Pseudo-Code

Wie immer gibt's reichlich Varianten, hier ist eine meiner.

Erst die Lösungsschritte in Pseudo-Code. Los geht’s:

Lösungsschritte
Schritt 1

Zuerst erstellen wir uns 2 Arrays.

Schritt 2

1 mit den Ziffern der Telefonnummer, und 1 mit allen Zeichen des Templates.

Schritt 3

Dann können wir die Anzahl der Rauten/Hashes im Template mit der Anzahl der Ziffern in der Telefonnummer vergleichen.

Schritt 4

Sollten wir weniger Ziffern als Rauten haben, können wir direkt "Invalid phone number" zurückgeben.

Schritt 5

Ansonsten loopen wir durch die Template-Zeichen und ersetzen jede Raute mit der aktuellen Ziffer der Telefonnummer.

Code

Geil. Übersetzen wir unseren Pseudo-Code in TypeScript:

Lösungsschritte
Meine erste Zeile:
export function formatNumber(number: number, template: string): string {
Erst die beiden Arrays:
const digits = [...number.toString()];
const templateChars = [...template];
Die Anzahl der Zeichen speichere ich mir auch gleich in einer Variablen ab (optional):
const numDigits = digits.length;
Dann die Anzahl der Rauten/Hashes im Template berechnen:
const numHashes = templateChars.filter((char) => char === "#").length;
Jetzt der Check, ob wir zuviel Rauten haben:
if (numDigits < numHashes) return "Invalid phone number";
Zum Schluss der Loop durch die Template-Zeichen:
  return templateChars
    .map((char) => (char === "#" ? digits.shift() : char))
    .join("");
}

Hier bietet sich .map() an, da das Array am Ende genauso viele Zeichen haben soll wie vorher.

Wenn das aktuelle Zeichen eine Raute ist, knapsen wir mit .shift() die erste Ziffer im Ziffer-Array ab und geben dieses zurück. Ansonsten belassen wir es beim aktuellen Zeichen. Das Ziffer-Array wird also immer kürzer.

Am Ende das Array wieder zu einem String joinen.

Das Ganze können wir mit dem return-Statement davor direkt zurückgeben.

Voilá! 💪

Fragen?

Komplettlösung
export function formatNumber(number: number, template: string): string {
  const digits = [...number.toString()];
  const templateChars = [...template];
  const numDigits = digits.length;
  const numHashes = templateChars.filter((char) => char === "#").length;

  if (numDigits < numHashes) return "Invalid phone number";

  return templateChars
    .map((char) => (char === "#" ? digits.shift() : char))
    .join("");
}

Feedback

Schreib mir!