`Map`-objektet
Denne artikkelen forklarer Map-objektet.
Vi forklarer trinn for trinn, fra grunnleggende operasjoner til praktiske eksempler som er nyttige i virkelige situasjoner.
YouTube Video
Map-objektet
Map er en samling som lagrer nøkkel-verdi-par. Det ligner på et objekt, men skiller seg ut ved at enhver type, slik som objekter, funksjoner eller primitive verdier, kan brukes som nøkler, og rekkefølgen på innsettingen bevares.
Grunnleggende om Map
Først skal vi se på hvordan man oppretter et Map og utfører grunnleggende operasjoner.
Følgende kode er et minimalt eksempel som oppretter et tomt kart, legger til nøkler og henter ut verdier.
1// Create an empty Map and add key-value pairs
2const m = new Map();
3m.set('a', 1);
4m.set('b', 2);
5
6console.log(m.get('a')); // 1
7console.log(m.size); // 2
- I denne koden kan du legge til elementer med
set, hente ut verdier medgetog sjekke antall elementer medsize. Mapopprettholder innsettingsrekkefølgen, noe som gjør det egnet for ordensavhengig prosessering.
Oppførsel til set, get, has og delete
Her er eksempler på typiske lese-, skrive-, eksistenssjekk- og sletteoperasjoner.
Med den følgende koden kan du sjekke returverdiene og effektene av hver metode.
1// Demonstrate set, get, has, and delete
2const m2 = new Map();
3m2.set('x', 10);
4console.log(m2.has('x')); // true
5console.log(m2.get('y')); // undefined
6
7m2.delete('x');
8console.log(m2.has('x')); // false
9
10// set returns the map itself, allowing method chaining
11m2.set('a', 1).set('b', 2);
12console.log(m2); // Map { 'a' => 1, 'b' => 2 }
getreturnererundefinedhvis nøkkelen ikke finnes.hassjekker om en nøkkel finnes, ogdeletefjerner en nøkkel.- Siden
setreturnerer selve kartet, er metodekjeding mulig.
Alle typer kan brukes som nøkkel (å bruke objekter som nøkler)
En av hovedfordelene med Map er at du kan bruke objekter direkte som nøkler.
Følgende eksempel viser hvordan man kan assosiere verdier i et Map ved å bruke objekter som nøkler.
1// Use objects as keys in a Map
2const keyObj = { id: 1 };
3const keyFunc = () => {};
4const objMap = new Map();
5
6// Another object with the same content but a different reference
7const anotherKeyObj = { id: 1 };
8
9objMap.set(keyObj, 'objectValue');
10objMap.set(keyFunc, 'functionValue');
11objMap.set(anotherKeyObj, 'anotherValue');
12
13console.log(objMap.get(keyObj)); // 'objectValue'
14console.log(objMap.get(keyFunc)); // 'functionValue'
15console.log(objMap.get(anotherKeyObj)); // 'anotherValue'
- Når man bruker objekter som nøkler, er det viktig at de har samme referanse. Selv om innholdet er det samme, vil objekter med forskjellige referanser bli behandlet som forskjellige, og er altså ikke samme nøkkel.
Iterasjon (løkker)
Map bevarer innsettingsrekkefølgen, så iterasjon brukes ofte.
Nedenfor viser vi hvordan man bruker for...of, forEach samt metodene keys(), values() og entries().
1// Iterating a Map with for...of and forEach
2const iterMap = new Map([['a', 1], ['b', 2], ['c', 3]]);
3
4// for...of over entries (default)
5for (const [key, value] of iterMap) {
6 console.log(key, value);
7}
8
9// forEach callback
10iterMap.forEach((value, key) => {
11 console.log(key, value);
12});
13
14// keys() and values()
15console.log([...iterMap.keys()]); // ['a','b','c']
16console.log([...iterMap.values()]); // [1,2,3]
entries()returnerer et array med[key, value]-par, som kan omgjøres til et array ved å bruke spread-syntaksen. Merk at tilbakeringeren forforEachmottar argumentene i rekkefølgenvalue, key.
Konvertering mellom Map og Object
Du kan konvertere et eksisterende objekt til et Map, eller konvertere et Map til et vanlig objekt eller array.
1// Convert between Map and Object / Array
2const obj = { a: 1, b: 2 };
3const mapFromObj = new Map(Object.entries(obj)); // Object -> Map
4console.log(mapFromObj.get('a')); // 1
5
6const objFromMap = Object.fromEntries(mapFromObj); // Map -> Object
7console.log(objFromMap); // { a: 1, b: 2 }
8
9const arrayFromMap = [...mapFromObj]; // Map -> Array of [key, value]
10console.log(arrayFromMap); // [['a',1], ['b',2]]
- Bruk av
Object.entriesogObject.fromEntriesgjør konvertering enkelt. Men siden objekt-nøkler er begrenset til strenger eller symboler, vil ikke-streng-nøkler gå tapt når man konverterer tilbake til et objekt.
Praktisk mønster: Frekvenstelling (Count Map)
Når du teller forekomsten av elementer i et array, gjør bruk av Map prosessen enklere.
Følgende kode er et eksempel på bruk av et Map for å telle frekvensen av strenger i et array og sortere dem.
1// Count frequencies with Map
2const arr = ['apple','banana','apple','orange','banana','apple'];
3const freq = new Map();
4
5for (const item of arr) {
6 freq.set(item, (freq.get(item) || 0) + 1);
7}
8
9console.log([...freq.entries()]); // [['apple',3], ['banana',2], ['orange',1]]
- Ved å bruke et Map kan du enkelt sjekke eksistens og oppdatere verdier. Dette kan også gjøres med objekter, men
Mapkan være mer intuitivt når du arbeider med vilkårlige nøkler.
Merknader om Map og JSON.stringify (serialisering)
JSON.stringify kan ikke serialisere et Map direkte. Hvis du må lagre et Map, må du først konvertere det.
Følgende eksempel viser hvordan man konverterer et Map til et array før det gjøres om til JSON, og hvordan man gjenoppretter det.
1// Serialize and deserialize a Map
2const m3 = new Map([['x', 1], ['y', 2]]);
3const json = JSON.stringify([...m3]); // convert to array first
4console.log(json); // '[["x",1],["y",2]]'
5
6const restored = new Map(JSON.parse(json));
7console.log(restored.get('x')); // 1
- Maps som må lagres eller overføres bør konverteres til arrays før serialisering. Når du skal gjenopprette, bruk
JSON.parsefor å gjøre det om til et array, og deretter konverter det tilbake til et Map.
Introduksjon til WeakMap og hvordan man bruker det
WeakMap skiller seg ut ved at nøklene har svake referanser (kan blir samlet inn av søppeloppsamlingen).
Det er nyttig for å holde cache eller metadata med objekter som nøkler, og frigir dem automatisk når nøkkelobjektet blir samlet inn.
1// WeakMap for metadata tied to object lifecycle
2const wm = new WeakMap();
3let obj = {};
4wm.set(obj, { meta: 'info' });
5console.log(wm.get(obj)); // { meta: 'info' }
6
7obj = null; // now the object can be GC'd and its entry removed from WeakMap
WeakMapkan ikke telles opp eller sjekkes størrelse på, men er nyttig for å forhindre minnelekkasjer.
Sammendrag
Map er en praktisk samling som, i motsetning til objekter, lar deg bruke hvilken som helst type som nøkkel og bevarer innsettingsrekkefølgen. Ved å forstå alt fra grunnleggende operasjoner til avansert bruk, kan du håndtere data mer fleksibelt og intuitivt. Ved å bruke Object og Map riktig i henhold til brukstilfellet, kan du forbedre klarheten og lesbarheten i koden betydelig.
Du kan følge med på artikkelen ovenfor ved å bruke Visual Studio Code på vår YouTube-kanal. Vennligst sjekk ut YouTube-kanalen.