Tracks
/
Swift
Swift
/
Übungen
/
Erfahrener Mixologe
Erfahrener Mixologe

Erfahrener Mixologe

Lernübung

Einführung

Switch

Eine switch-Anweisung ermöglicht es dir, einen Wert mit mehreren möglichen übereinstimmenden Werten zu vergleichen. Damit kannst du prägnanteren Code schreiben als mit mehreren else-if-Anweisungen. Eine switch-Anweisung beginnt mit dem Schlüsselwort switch, gefolgt von dem Wert, der verglichen werden soll. Danach definierst du die Fälle mit dem Schlüsselwort case, gefolgt von dem Wert, mit dem verglichen wird. Mit dem Schlüsselwort default definierst du den Standardfall, wenn keiner der Fälle passt. Wie else-if-Anweisungen führen switch-Anweisungen nur den Block aus, der zum ersten passenden Fall gehört.

switch value {
case 1:
    print("One")
case 2:
    print("Two")
default:
    print("Other")
}

Schauen wir uns das folgende Beispiel an:

if str == "apple" {
    print("Let's bake an apple crumble")
} else if str == "lemon" {
    print("Let's bake a lemon meringue pie!")
} else if str == "peach" {
    print("Let's bake a peach pie!")
} else {
    print("Let's buy ice cream.")
}

Das lässt sich stattdessen auch so schreiben:

switch str {
case "apple":
    print("Let's bake an apple crumble")
case "lemon":
    print("Let's bake a lemon meringue pie!")
case "peach":
    print("Let's bake a peach pie!")
default:
    print("Let's buy ice cream.")
}

while-Schleifen

Eine while-Schleife ist eine Anweisung, mit der du Code so lange ausführen kannst, wie eine bestimmte Bedingung wahr ist. Swift bietet zwei Arten von while-Schleifen: while- und repeat-while-Schleifen. Bei einer while-Schleife wird die Bedingung ausgewertet, bevor der Schleifenblock ausgeführt wird. Ist die Bedingung falsch, wird der Schleifenblock gar nicht ausgeführt. while-Schleifen haben in Swift folgenden Aufbau:

while <#condition#> {
  <#code#>
}

Hier wird die Schleife so lange ausgeführt, wie count größer als 0 ist, und gibt dabei die Zahlen 2, 1 und „Liftoff!“ aus.

var count = 2
while count > 0 {
  print("\(count)…")
  count -= 1
}
print("Liftoff!")

// prints:
// 2…
// 1…
// Liftoff!

Eine repeat-while-Schleife ähnelt einer while-Schleife, doch die Bedingung wird ausgewertet, nachdem der Schleifenblock ausgeführt wurde. Das heißt, der Schleifenblock wird immer mindestens einmal ausgeführt, selbst wenn die Bedingung falsch ist. repeat-while-Schleifen haben in Swift folgenden Aufbau:

repeat {
  <#code#>
} while <#condition#>

Hier wird die Schleife nur einmal ausgeführt, da die Bedingung falsch ist. Da es eine repeat-while-Schleife ist, wird der Schleifenblock einmal ausgeführt, bevor die Bedingung ausgewertet wird.

var count = 2
repeat {
  print("\(count)…")
} while count < 0
print("Liftoff!")

Kontrollübertragung

Swift hat einige Anweisungen, mit denen du den normalen Kontrollfluss von Schleifen ändern kannst. Man nennt sie Kontrollübertragungsanweisungen. return kennst du bereits; in diesem Konzept lernst du weitere kennen, darunter continue, break und Labels. fallthrough behandeln wir in diesem Konzept nicht, aber du kannst im Swift-Buch darüber lesen.

Continue

Manchmal ist es nötig, vorzeitig zur nächsten Iteration einer Schleife zu springen, ohne die übrigen Anweisungen in der aktuellen Iteration der Schleife auszuführen. Dafür kannst du das Schlüsselwort continue verwenden. Wenn continue ausgeführt wird, springt die Schleife zur nächsten Prüfung, ob die nächste Iteration der Schleife ausgeführt werden kann, also zum while in while- und repeat-while-Schleifen oder zur Prüfung, ob die Sequenz in for-in-Schleifen ein weiteres Element enthält.

count = 1
while count < 6 {
  count += 1
  if count == 4 { continue }
  print(count)
}

// prints:
// 2
// 3
// 5

Break

Break wird verwendet, um eine Schleife vorzeitig zu verlassen. Wenn break ausgeführt wird, wird die Schleife sofort beendet und das Programm fährt mit der ersten Anweisung nach der Schleife fort.

for fruit in ["banana", "grapes", "apple", "strawberry", "kiwi", "lemon"] {
  if !fruit.count.isMultiple(of: 2) { break }
  print(fruit)
}

// prints:
// banana
// grapes

Labels

Wenn Schleifen verschachtelt sind, kann es vorkommen, dass du mit break oder continue die äußeren Schleifen verlassen oder neu starten möchtest, die die Schleife enthalten, in der break oder continue stehen. In solchen Fällen kannst du mit Labels angeben, welche Schleife verlassen oder neu gestartet werden soll. Du kannst eine Schleife mit einem Label versehen, indem du einen Namen gefolgt von einem Doppelpunkt vor das while, repeat oder for setzt, das die Schleife beginnt.

Um die Wirkung von Labels zu sehen, schauen wir uns die folgende Schleife an.

outerLoop: for fruit in ["banana", "grapes", "apple", "strawberry", "kiwi", "lemon"] {
  print("\n--- \(fruit) ---")
  for letter in fruit {
    guard letter != "n" else { break outerLoop }
    print(letter)
  }
}

// prints:
// --- banana ---
// b
// a

Anleitung

Du bist ein erfahrener Mixologe und mixt leckere Drinks, die die Leute abends beim Ausgehen genießen. Aber du hast dir gedacht, dass du dir das Leben leichter machen könntest, indem du ein bisschen Code schreibst, der dir bei deiner Arbeit hilft.

1. Ermittle, wie lange die Zubereitung einer Bestellung dauert

Die Zubereitung verschiedener Drinks dauert unterschiedlich lange:

  • "beer", "soda" und "water" dauern jeweils 0,5 Minuten.
  • "shot" dauert 1,0 Minuten, "mixed drink" dauert 1,5 Minuten.
  • "fancy drink" dauert 2,5 Minuten.
  • "frozen drink" dauert 3,0 Minuten.

Implementiere die Funktion timeToPrepare(drinks:), die das Argument drinks entgegennimmt. Es enthält ein Array aus Strings, die die Drinks repräsentieren, die zubereitet werden müssen. Die Funktion sollte die Gesamtzeit zurückgeben, die benötigt wird, um alle Drinks im Array zuzubereiten.

timeToPrepare(drinks: ["beer", "frozen drink", "shot"])
// returns 4.5

2. Fülle deinen Vorrat an Limettenstücken auf

Eine der ersten Aufgaben, wenn du deine Schicht beginnst, ist sicherzustellen, dass dein kleines Behältnis mit Limettenstücken für die kommende Schicht gut gefüllt ist. Du hast Limetten in verschiedenen Größen, die unterschiedlich viele Stücke ergeben: Aus einer „small“ Limette bekommst du 6 Stücke, aus einer „medium“ Limette 8 Stücke und aus einer „large“ Limette 10 Stücke.

Solange du noch mehr Stücke brauchst und noch mehr Limetten zum Aufschneiden hast, nimm die erste Limette aus dem Array und ziehe die entsprechende Anzahl an Stücken von der Menge ab, die du brauchst. Mach so lange weiter, bis du keine weiteren Stücke mehr brauchst oder dir die Limetten ausgehen.

Implementiere die Funktion makeWedges(needed:limes:). Sie nimmt die Argumente needed und limes entgegen. needed enthält die Anzahl der Stücke, die du aufschneiden musst, und limes ein Array aus Strings mit den Größen der Limetten, die du zum Aufschneiden zur Verfügung hast. Die Funktion sollte die Anzahl der Limetten zurückgeben, die du aufgeschnitten hast.

makeWedges(needed: 25, limes: ["small", "small", "large", "medium", "small"])
// returns 4

3. Beende deine Schicht

Glückwunsch! Dein langer Arbeitstag ist fast vorbei und du gehst bald nach Hause, um an deiner neuen App zu arbeiten. Aber du hast noch eine ganze Reihe von Drinkbestellungen zuzubereiten, bevor du die Bestellungen an die nächste Schicht übergeben und gehen kannst.

Solange dir noch Zeit in deiner Schicht bleibt, bereitest du die erste Bestellung im Array zu und entfernst diese Bestellung anschließend aus dem Array. Danach kannst du die Zeit, die die Zubereitung dieser Bestellung gedauert hat, entsprechend deiner Funktion timeToPrepare(drinks:) von der verbleibenden Zeit deiner Schicht abziehen.

Implementiere die Funktion finishShift(minutesLeft:remainingOrders:), die die Anzahl der Minuten, die dir in deiner Schicht noch bleiben (garantiert größer als 0), und ein nicht leeres Array mit Drinkbestellungen entgegennimmt. Die Funktion sollte das Array mit den Bestellungen zurückgeben, die du vor dem Ende deiner Schicht nicht mehr geschafft hast.

finishShift(minutesLeft: 5, remainingOrders: [["beer", "frozen drink", "shot"], ["fancy drink", "soda"], ["beer", "beer", "water"], ["mixed drink", "frozen drink"]])
// returns [["beer", "beer", "water"], ["mixed drink", "frozen drink"]]

4. Verfolge bestimmte Bestellungen

Um sicherzustellen, dass Bier und Soda frisch bleiben, musst du ihre Bestellungen zusammen mit den Uhrzeiten nachverfolgen, zu denen diese Bestellungen aufgegeben wurden.

Implementiere die Funktion orderTracker(orders: [(drink: String, time: String)]) -> (beer: (first: String, last: String, total: Int)?, soda: (first: String, last: String, total: Int)?). Wenn sie eine Liste von Bestellungen und Uhrzeiten erhält, gibt sie ein Paar optionaler Tupel zurück mit den Uhrzeiten der ersten und letzten Bestellung von Bier und Soda sowie der Gesamtzahl der Bestellungen von jedem, und nil, wenn keine Bestellungen für diese Getränke aufgegeben wurden. Alle anderen Drinks musst du nicht verfolgen.

Implementiere die Funktion orderTracker(orders:), die ein Array aus Tupeln entgegennimmt, wobei jedes Tupel das bestellte Getränk und die Uhrzeit enthält, zu der die Bestellung aufgegeben wurde. Die Funktion sollte ein Tupel zurückgeben mit der ersten und letzten Uhrzeit, zu der Bier bestellt wurde, der Gesamtzahl der Bierbestellungen, der ersten und letzten Uhrzeit, zu der Soda bestellt wurde, sowie der Gesamtzahl der Sodabestellungen. Es sollte als Tupel im folgenden Format zurückgegeben werden: (beer: (first: String, last: String, total: Int)?, soda: (first: String, last: String, total: Int)?).

let orders = [
    (drink: "beer", time: "10:01"), (drink: "frozen drink", time: "10:02"),
    (drink: "shot", time: "10:05"), (drink: "fancy drink", time: "10:06"),
    (drink: "soda", time: "10:09"), (drink: "beer", time: "10:15"), (drink: "beer", time: "10:22"),
    (drink: "water", time: "10:26"), (drink: "mixed drink", time: "10:28"),
    (drink: "frozen drink", time: "10:33"),
]

orderTracker(orders: orders)

// returns (beer: (first "10:01", last "10:22", total 3), soda: (first "10:09", last "10:09", total 1))
Über GitHub bearbeiten Der Link öffnet sich in einem neuen Fenster oder Tab
Swift Exercism

Bereit, mit Erfahrener Mixologe zu starten?

Melde dich bei Exercism an, um Swift mit 35 Konzepte116 Übungen und echtem menschlichen Mentoring zu lernen und zu meistern, alles kostenlos.