Funktionen in map und filter
Arrays haben Methoden, die eine Funktion als Argument nehmen. Zwei davon werden ständig benutzt, und für dich sind sie neu: map und filter. Beide sind reines JavaScript; TypeScript fügt etwas Nützliches hinzu.
map erzeugt ein neues Array. Es ruft deine Funktion für jedes Element auf und legt das, was die Funktion zurückgibt, in der gleichen Reihenfolge in das neue Array:
const truhen = [10, 25, 40];
const verdoppelt = truhen.map(gold => gold * 2);
console.log(verdoppelt);
console.log(truhen);Das gibt aus:
[20, 50, 80]
[10, 25, 40]map hat gold => gold * 2 dreimal aufgerufen, mit 10, 25 und 40, und die Ergebnisse gesammelt. Das ursprüngliche Array truhen hat sich nicht geändert. Es tut dasselbe wie diese Schleife, nur in einer Zeile:
const verdoppelt: number[] = [];
for (const gold of truhen) {
verdoppelt.push(gold * 2);
}Die Funktion darf einen Wert eines anderen Typs zurückgeben. Dann hat das neue Array Elemente dieses Typs:
const namen = ["Kira", "Bruno", "Lena"];
console.log(namen.map(name => name.toUpperCase()));
console.log(namen.map(name => name.length));Das gibt aus:
["KIRA", "BRUNO", "LENA"]
[4, 5, 4]Beachte, dass gold und name keinen Typ haben und TypeScript sich nicht daran stört. Das ist das Nützliche: TypeScript weiß, dass truhen ein number[] ist, also bekommt die Funktion, die map übergeben wird, Zahlen, und gold ist eine number. Der Parameter bekommt seinen Typ von der Stelle, an der die Funktion geschrieben steht (Programmierer nennen das kontextuelle Typisierung). TypeScript weiß auch, was map zurückgibt: aus gold * 2 ein Array aus Zahlen, number[]. Und weil es weiß, dass name ein String ist, prüft es, was du damit tust:
const namen = ["Kira", "Bruno", "Lena"];
const verdoppelt = namen.map(name => name * 2);main.ts(2,38): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.Das funktioniert nur, wenn die Funktion genau dort geschrieben steht, wo sie verwendet wird, als Argument. Eine Pfeilfunktion, die für sich in einer Variablen gespeichert ist, braucht weiterhin Typen, denn TypeScript weiß nicht, wo sie verwendet werden wird:
const verdoppeln = gold => gold * 2;main.ts(1,20): error TS7006: Parameter 'gold' implicitly has an 'any' type.filter erzeugt ebenfalls ein neues Array, behält aber nur manche Elemente: die, für die deine Funktion true zurückgibt:
const monsterListe = [
{ name: "Goblin", kraft: 4 },
{ name: "Troll", kraft: 15 },
{ name: "Wolf", kraft: 8 },
{ name: "Drache", kraft: 40 },
];
const starke = monsterListe.filter(monster => monster.kraft > 10);
console.log(starke);
console.log(starke.map(monster => monster.name));Das gibt aus:
[{ name: "Troll", kraft: 15 }, { name: "Drache", kraft: 40 }]
["Troll", "Drache"]Hier bekommt monster den Typ der Elemente des Arrays, { name: string; kraft: number; }, deshalb fängt TypeScript einen Tippfehler ab:
const monsterListe = [
{ name: "Goblin", kraft: 4 },
{ name: "Troll", kraft: 15 },
{ name: "Wolf", kraft: 8 },
{ name: "Drache", kraft: 40 },
];
const starke = monsterListe.filter(monster => monster.kraf > 10);main.ts(7,55): error TS2551: Property 'kraf' does not exist on type '{ name: string; kraft: number; }'. Did you mean 'kraft'?Das Ergebnis von filter hat denselben Typ wie das ursprüngliche Array, du kannst also damit weitermachen. Die letzte Zeile des Beispiels ruft map auf dem Ergebnis auf, um nur die Namen zu bekommen.
Typische Fehler:
- Geschweifte Klammern ohne
return:truhen.map(gold => { gold * 2 })ergibt[undefined, undefined, undefined], und derselbe Fehler infilterergibt[]. TypeScript meldet das hier nicht, schreibe bei geschweiften Klammern alsoreturn. - Erwarten, dass
mapoderfilterdas Array ändern. Das tun sie nicht: Sie geben ein neues Array zurück. Speichere es in einer Variablen oder verwende es sofort.
So schreibst du es:
Anweisungen
- 1
Glückstag: Das Gold in jeder Truhe verdoppelt sich. Rufe
mapauftruhenauf, um ein ArraydoppeltesGoldmit dem doppelten Gold jeder Truhe zu erzeugen. - 2
Gib
doppeltesGoldund danntruhenaus, um zu sehen, dassmapdas ursprüngliche Array nicht verändert hat. Das Programm gibt aus:[24, 60, 14, 90] [12, 30, 7, 45] - 3
Kira kämpft nur gegen die starken Monster, die mit einer Kraft über 10. Rufe
filteraufmonsterListeauf, um ein ArraystarkeMonstermit ihnen zu erzeugen. - 4
Gib
starkeMonsteraus und dann nur die Namen der starken Monster: Rufe dazumapaufstarkeMonsterauf. Am Ende gibt das Programm aus:[{ name: "Troll", kraft: 25 }, { name: "Skelett", kraft: 12 }] ["Troll", "Skelett"]