Codewars Lösung | Naming Files


coden
Codewars. Achieve mastery through challenge.
Daniel Kaser|17. Februar 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:Naming Files
Level:7 kyu
Sprache:TypeScript

Beschreibung:

Naming multiple files can be a pain sometimes.

Task:

Your job here is to create a function that will take three parameters, fmt, nbr and start, and create an array of nbr elements formatted according to frm with the starting index start. fmt will have `` inserted at various locations; this is where the file index number goes in each file.

Description of edge cases:

  1. If nbr is less than or equal to 0, or not whole, return an empty array.
  2. If fmt does not contain '', just return an array with nbr elements that are all equal to fmt.
  3. If start is not an integer, return an empty array.

What each parameter looks like:

frm.class #=> String
  : "text_to_stay_constant_from_file_to_file "
nbr.class #=> Fixnum
  : number_of_files
start.class #=> Fixnum
  : index_no_of_first_file
name_file(frm, nbr, start).class #=> Array(Fixnum)
frm.class #=> String
  : "text_to_stay_constant_from_file_to_file "
nbr.class #=> Int32
  : number_of_files
start.class #=> Int32
  : index_no_of_first_file
name_file(frm, nbr, start).class #=> Array(Int32)
type(frm) #=> str
  : "text_to_stay_constant_from_file_to_file "
type(nbr) #=> int
  : number_of_files
type(start) #=> int
  : index_no_of_first_file
type(name_file(frm, nbr, start)) #=> list
typeof frm #=> 'string'
  : "text_to_stay_constant_from_file_to_file "
typeof nbr #=> 'number'
  : number_of_files
typeof start #=> 'number'
  : index_no_of_first_file
typeof (nameFile(frm, nbr, start)) #=> 'array'
typeof frm #=> 'string'
  : "text_to_stay_constant_from_file_to_file "
typeof nbr #=> 'number'
  : number_of_files
typeof start #=> 'number'
  : index_no_of_first_file
typeof (nameFile(frm, nbr, start)) #=> 'array'

Some examples:

name_file('IMG ', 4, 1)
  #=> ['IMG 1', 'IMG 2', 'IMG 3', 'IMG 4']
name_file('image #.jpg', 3, 7)
  #=> ['image #7.jpg', 'image #8.jpg', 'image #9.jpg']
name_file('# #', 3, -2)
  #=> ['#-2 #-2', '#-1 #-1', '#0 #0']
name_file("IMG ", 4, 1)
  #=> ["IMG 1", "IMG 2", "IMG 3", "IMG 4"])
name_file("image #.jpg", 3, 7)
  #=> ["image #7.jpg", "image #8.jpg", "image #9.jpg"]
name_file("# #", 3, -2)
  #=> ["#-2 #-2", "#-1 #-1", "#0 #0"]
name_file("IMG ", 4, 1)
  #=> ["IMG 1", "IMG 2", "IMG 3", "IMG 4"])
name_file("image #.jpg", 3, 7)
  #=> ["image #7.jpg", "image #8.jpg", "image #9.jpg"]
name_file("# #", 3, -2)
  #=> ["#-2 #-2", "#-1 #-1", "#0 #0"]
nameFile("IMG ", 4, 1)
  #=> ["IMG 1", "IMG 2", "IMG 3", "IMG 4"])
nameFile("image #.jpg", 3, 7)
  #=> ["image #7.jpg", "image #8.jpg", "image #9.jpg"]
nameFile("# #", 3, -2)
  #=> ["#-2 #-2", "#-1 #-1", "#0 #0"]
nameFile("IMG ", 4, 1)
  #=> ["IMG 1", "IMG 2", "IMG 3", "IMG 4"])
nameFile("image #.jpg", 3, 7)
  #=> ["image #7.jpg", "image #8.jpg", "image #9.jpg"]
nameFile("# #", 3, -2)
  #=> ["#-2 #-2", "#-1 #-1", "#0 #0"]

Also check out my other creations — Elections: Weighted Average, Identify Case, Split Without Loss, Adding Fractions, Random Integers, Implement String#transpose, Implement Array#transpose!, Arrays and Procs #1, and Arrays and Procs #2.

If you notice any issues or have any suggestions/comments whatsoever, please don't hesitate to mark an issue or just comment. Thanks!

Quelle: codewars.com

Lösung

Pseudo-Code

Die Beschreibung dieses Katas ist sehr abschreckend geschrieben. Aber so schlimm ist es gar nicht...

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

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

Lösungsschritte
Schritt 1

Als Erstes gebe ich den Argumenten aussagekräftigere Namen. Mit fmt und nbr kann ich leider überhaupt nix anfangen...

Schritt 2

fmt wird bei mir also zu template und nbr zu numFiles.

Schritt 3

Dann müssen wir kucken, dass wir für die Fälle in denen numFiles kleiner oder gleich 0 ist, ein leeres Array returnen.

Schritt 4

Das gleiche gilt, wenn numFiles oder start keine Ganze Zahl ist.

Schritt 5

Dann können wir uns ein Array erstellen mit numFiles-vielen Elementen.

Schritt 6

Durch dieses Array brauchen wir nur noch zu loopen und und ein neues Array zurückgeben.

Schritt 7

Dabei ersetzen wir jedes <index_no> mit der aktuellen Index-Nummer.

Code

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

Lösungsschritte
Meine erste Zeile (ich habe fmt und nbr umbenannt):
export function nameFile(template: string, numFiles: number, start: number): string[] {
Erst kümmern wir uns um den Fall numFiles <= 0:
if (numFiles <= 0) return [];
Dann die Fälle in denen numFiles oder start keine ganze Zahl sind:
if (!Number.isInteger(numFiles) || !Number.isInteger(start)) return [];
Jetzt können wir unser Array erstellen:
Array(numFiles).fill("x");

Ich fülle es gleich mit x'n. Man kann auch jeden beliebigen anderen String (oder Zahl nehmen).

Dann der Loop durch unser neues Array:
    .map((_, i) => {

Ich hänge hier einfach .map() dran. Wir brauchen hier nur den Index. Darum nenne ich das erste Argument _. Das ist Konvention für: “Brauchen wa nich.”

Jetzt alle <index_no> im template-String mit der aktuellen Index-Nummer ersetzen:
      const currIndexNo = start + i;
      return template.replace(/<index_no>/g, currIndexNo.toString());
    });
}

Der Übersichtlichkeit halber speichere ich die Index-Nummer vorher in einer Variablen. Zum Finden aller <index_no>-Strings verwende ich eine RegEx.

Zum Schluss noch das Ergebnis zurückgeben:
...
  return Array(numFiles)
    .fill("x")
...

Das return können wir gleich oben beim Erstellen des Arrays ansetzen.

Voilá! 💪

Fragen?

Komplettlösung
export function nameFile(
  template: string,
  numFiles: number,
  start: number,
): string[] {
  if (numFiles <= 0) return [];
  if (!Number.isInteger(numFiles) || !Number.isInteger(start)) return [];

  return Array(numFiles)
    .fill("x")
    .map((_, i) => {
      const currIndexNo = start + i;
      return template.replace(/<index_no>/g, currIndexNo.toString());
    });
}

Feedback

Schreib mir!