Kurz: final haeufigkeit = <String, int>{}; for (final w in woerter) { haeufigkeit.update(w, (n) => n + 1, ifAbsent: () => 1); } final top = haeufigkeit.entries.toList() ..sort((a, b) { final c = b.value.compareTo(a.value).
Teil des Kurses Dart
Projekt 1: Wörter zählen
void main() {
const text = '''
Dart ist schnell. Dart ist modern, und Dart macht Spaß!
Modern und schnell: das ist Dart.
''';
final woerter = RegExp(r'[a-zäöüß]+')
.allMatches(text.toLowerCase())
.map((m) => m.group(0)!)
.toList();
final haeufigkeit = <String, int>{};
for (final w in woerter) {
haeufigkeit.update(w, (n) => n + 1, ifAbsent: () => 1);
}
final top = haeufigkeit.entries.toList()
..sort((a, b) {
final c = b.value.compareTo(a.value);
return c != 0 ? c : a.key.compareTo(b.key);
});
print('${woerter.length} Wörter, ${haeufigkeit.length} verschiedene');
for (final e in top.take(4)) {
print('${e.key.padRight(8)} ${'#' * e.value} ${e.value}');
}
print('Längstes Wort: ${woerter.reduce((a, b) => a.length >= b.length ? a : b)}');
}Ausgabe:
16 Wörter, 8 verschiedene
dart #### 4
ist ### 3
modern ## 2
schnell ## 2
Längstes Wort: schnellProjekt 2: Lagerverwaltung mit Klassen
class Artikel {
final String name;
final double preis;
int menge;
Artikel(this.name, this.preis, this.menge);
double get wert => preis * menge;
@override
String toString() => '${name.padRight(10)} $menge x ${preis.toStringAsFixed(2)} = ${wert.toStringAsFixed(2)}';
}
class Lager {
final Map<String, Artikel> _artikel = {};
void aufnehmen(String name, double preis, int menge) {
if (menge <= 0) throw ArgumentError('Menge muss positiv sein');
_artikel.update(name, (a) { a.menge += menge; return a; }, ifAbsent: () => Artikel(name, preis, menge));
}
void entnehmen(String name, int menge) {
final a = _artikel[name];
if (a == null) throw StateError('Artikel $name unbekannt');
if (a.menge < menge) throw StateError('Nur ${a.menge} von $name vorhanden');
a.menge -= menge;
}
double get gesamtwert => _artikel.values.fold(0.0, (s, a) => s + a.wert);
List<Artikel> get sortiert => _artikel.values.toList()..sort((a, b) => b.wert.compareTo(a.wert));
}
void main() {
final lager = Lager();
lager.aufnehmen('Schrauben', 0.12, 500);
lager.aufnehmen('Bohrer', 14.9, 12);
lager.aufnehmen('Schrauben', 0.12, 250);
lager.aufnehmen('Muttern', 0.08, 300);
for (final test in [() => lager.entnehmen('Bohrer', 5), () => lager.entnehmen('Bohrer', 50), () => lager.entnehmen('Nägel', 1), () => lager.aufnehmen('X', 1, 0)]) {
try {
test();
print('ok');
} catch (e) {
print('Fehler: ${e is Error ? e.toString().replaceFirst(RegExp(r'^\w+: '), '') : e}');
}
}
lager.sortiert.forEach(print);
print('Gesamtwert: ${lager.gesamtwert.toStringAsFixed(2)}');
}Ausgabe:
ok
Fehler: Bad state: Nur 7 von Bohrer vorhanden
Fehler: Bad state: Artikel Nägel unbekannt
Fehler: Invalid argument(s): Menge muss positiv sein
Bohrer 7 x 14.90 = 104.30
Schrauben 750 x 0.12 = 90.00
Muttern 300 x 0.08 = 24.00
Gesamtwert: 218.30Projekt 3: Algorithmen
int fib(int n, [Map<int, int>? memo]) {
memo ??= {};
if (n < 2) return n;
return memo[n] ??= fib(n - 1, memo) + fib(n - 2, memo);
}
List<int> primzahlen(int bis) {
final sieb = List.filled(bis + 1, true);
sieb[0] = sieb[1] = false;
for (var i = 2; i * i <= bis; i++) {
if (sieb[i]) { for (var j = i * i; j <= bis; j += i) { sieb[j] = false; } }
}
return [for (var i = 0; i <= bis; i++) if (sieb[i]) i];
}
int? binaereSuche(List<int> liste, int ziel) {
var lo = 0, hi = liste.length - 1;
while (lo <= hi) {
final mitte = (lo + hi) ~/ 2;
if (liste[mitte] == ziel) return mitte;
if (liste[mitte] < ziel) { lo = mitte + 1; } else { hi = mitte - 1; }
}
return null;
}
bool istPalindrom(String s) {
final sauber = s.toLowerCase().replaceAll(RegExp(r'[^a-zäöüß]'), '');
return sauber == sauber.split('').reversed.join();
}
List<int> quicksort(List<int> l) {
if (l.length < 2) return l;
final pivot = l[l.length ~/ 2];
return [
...quicksort(l.where((x) => x < pivot).toList()),
...l.where((x) => x == pivot),
...quicksort(l.where((x) => x > pivot).toList()),
];
}
void main() {
print(fib(60));
print(primzahlen(50));
print('${binaereSuche([1, 3, 5, 7, 9, 11], 7)} ${binaereSuche([1, 3, 5], 4)}');
print('${istPalindrom('A man, a plan, a canal: Panama')} ${istPalindrom('Dart')}');
print(quicksort([5, 2, 9, 1, 5, 6, 3]));
print([for (var i = 1; i <= 15; i++) i % 15 == 0 ? 'FizzBuzz' : i % 3 == 0 ? 'Fizz' : i % 5 == 0 ? 'Buzz' : '$i'].join(' '));
}Ausgabe:
1548008755920
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
3 null
true false
[1, 2, 3, 5, 5, 6, 9]
1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzzMerke
- Mit
Map.update, Sortierung mit Vergleichsfunktion undRegExpentstehen Auswertungen in wenigen Zeilen - Klassen kapseln Zustand, Exceptions melden Fehler;
ArgumentErrorundStateErrorsind Standardfehler - Memoization (
??=), Sieb, binäre Suche und Quicksort sind Standardübungen - Collection
forundiferzeugen Listen deklarativ
Übungsaufgabe
Erweitere das Lager um eine Methode bericht(), die Artikel unter einer Mindestmenge ausgibt.
Quiz zur Selbstkontrolle
Was macht Map.update mit ifAbsent?
- Ändert vorhandene Werte, legt sonst einen neuen an (richtig)
- Löscht Schlüssel
- Sortiert die Map
- Kopiert die Map
??= …?
- Berechnet und speichert den Wert nur, wenn er noch fehlt (richtig)
- Löscht memo
- Vergleicht memo
- Wirft einen Fehler
Welche Klasse ist für Programmierfehler gedacht?
- Error (z. B. ArgumentError, StateError) (richtig)
- Exception allein
- String
- Future
Weiter im Kurs
Zurück: Flutter und das Dart-Ökosystem
Weiter: Referenz und Spickzettel
Alle Kapitel: Dart im Überblick