`Set`-object
Dit artikel legt het Set-object uit.
We zullen het Set-object uitleggen met praktische voorbeelden.
YouTube Video
Set-object
Set is een ingebouwd object waarmee je verzamelingen van unieke, niet-gedupliceerde waarden kunt beheren. Het maakt het eenvoudiger om dubbele waarden te verwijderen en te controleren op bestaan dan met arrays, en maakt verzamelbewerkingen zoals unie en doorsnede makkelijker te implementeren.
Basis: Sets maken en gebruiken
Laten we eerst kijken hoe je een Set maakt, elementen toevoegt en verwijdert, controleert op bestaan en de grootte opvraagt.
Hieronder volgt een basisvoorbeeld waarin een nieuwe Set wordt gemaakt en de methoden add, has, delete en size worden getoond.
1// Create a Set and demonstrate add, has, delete, and size
2const s = new Set();
3
4s.add(1);
5s.add(2);
6s.add(2); // duplicate, ignored
7
8console.log(s.has(1)); // true
9console.log(s.has(3)); // false
10
11s.delete(2);
12console.log(s.size); // 1
13
14console.log([...s]); // [1]
- Zoals in deze code te zien is, verwijdert
Setautomatisch dubbele primitieve waarden en kun je het aantal elementen verkrijgen metsize.
Iteratiemethoden
Set is iterabel, dus je kunt erover itereren met for...of of forEach. De volgorde is de invoegvolgorde.
Hier zijn typische manieren om for...of en forEach te gebruiken.
1// Iterate a Set with for...of and forEach
2const s = new Set(['a', 'b', 'c']);
3
4for (const v of s) {
5 console.log('for...of:', v);
6}
7
8s.forEach((value, sameValue, setRef) => {
9 // Note: second arg is same as first for Set API to match Map signature
10 console.log('forEach:', value);
11});- De callback-signatuur voor
forEachisvalue, value, set(voor compatibiliteit met Map), maar in de praktijk heb je meestal alleen het eerstevalue-argument nodig.
Conversie tussen arrays en sets (handig om duplicaten te verwijderen)
Hier laten we een eenvoudige techniek zien om duplicaten uit een array te verwijderen, en hoe je een Set weer omzet naar een array.
Hieronder een voorbeeld om duplicaten uit een array te verwijderen door deze via een Set te halen.
1// Deduplicate an array using Set
2const arr = [1, 2, 2, 3, 3, 3];
3const deduped = [...new Set(arr)];
4console.log(deduped); // [1, 2, 3]
5
6// Convert a Set to an array using Array.from
7const s = new Set([4, 5, 6]);
8const arrFromSet = Array.from(s);
9console.log(arrFromSet); // [4, 5, 6]
- Dit patroon is kort en snel, en wordt daarom vaak gebruikt om duplicaten uit arrays te verwijderen. Het is vooral effectief voor primitieve waarden.
Objecten en referentieafhandeling
Objecten in een Set worden vergeleken op basis van referentie, dus verschillende instanties met dezelfde inhoud worden als aparte elementen beschouwd.
De volgende code demonstreert wat er gebeurt als je objecten toevoegt aan een Set.
1// Objects are compared by reference in a Set
2const obj1 = { x: 1 };
3const obj2 = { x: 1 };
4
5const s = new Set();
6s.add(obj1);
7s.add(obj2);
8
9console.log(s.size); // 2 (different references)
10console.log(s.has(obj1)); // true
11console.log(s.has({ x: 1 })); // false (different object)
- Dubbelherkenning voor objecten is gebaseerd op referentie-identiteit, dus als je wilt dedupliceren op basis van alleen de inhoud van objecten, moet je ze serialiseren of op een andere manier verwerken.
Speciale waarden: omgaan met NaN en -0/+0
Set gebruikt de Same-value-zero vergelijkingsregel om waarde-gelijkheid te bepalen. Deze vergelijkingsmethode heeft de volgende eigenschappen met betrekking tot getallen:.
NaNwordt beschouwd als gelijk aanNaN.- Positieve
+0en negatieve-0worden niet onderscheiden en worden als dezelfde waarde behandeld.
Daarom treedt het volgende gedrag op wanneer je deze waarden toevoegt aan een Set:.
1// NaN and zero behavior in Set
2const s = new Set();
3
4s.add(NaN);
5s.add(NaN);
6console.log(s.size); // 1 (NaN considered the same)
7
8s.add(+0);
9s.add(-0);
10console.log(s.size); // still 2 (NaN + 0)
11console.log([...s]); // [NaN, 0] (order may vary but only one zero)
- Bij normale vergelijking (
NaN === NaN) geeft ditfalse, maar binnen eenSetworden alleNaN-waarden als 'dezelfde waarde' beschouwd. - +0 en -0 zijn wiskundig te onderscheiden, maar in een
Setworden ze gewoon als0behandeld. - Als resultaat blijft er slechts één
NaNen één0over in deSet. - De vergelijkingsregel van
Setlijkt opObject.is, maar is niet precies hetzelfde.Object.is(+0, -0)geeftfalseterug, maar in eenSetworden ze als identiek beschouwd. Let goed op dit verschil.
Veelgebruikte functionaliteit: setoperaties (unie, doorsnede, verschil)
Setoperaties kunnen duidelijker worden geschreven met behulp van Set. Hieronder vind je veelgebruikte implementatievoorbeelden.
Hier zijn voorbeelden van functies voor union, intersection, en difference.
1// Set operations: union, intersection, difference
2function union(a, b) {
3 return new Set([...a, ...b]);
4}
5
6function intersection(a, b) {
7 return new Set([...a].filter(x => b.has(x)));
8}
9
10function difference(a, b) {
11 return new Set([...a].filter(x => !b.has(x)));
12}
13
14// Demo
15const A = new Set([1, 2, 3]);
16const B = new Set([3, 4, 5]);
17
18console.log('union', [...union(A, B)]); // [1,2,3,4,5]
19console.log('intersection', [...intersection(A, B)]); // [3]
20console.log('difference A\\B', [...difference(A, B)]); // [1,2]
- Setoperaties kun je eenvoudig schrijven door filters te gebruiken in combinatie met
Seten arrays. Bij grote datasets zorgt de O(1)-prestatie vanhaservoor dat bewerkingen sneller verlopen.
Praktisch voorbeeld: verschillen tussen arrays vinden (toegevoegde/verwijderde items detecteren)
Het volgende voorbeeld laat zien hoe je een Set gebruikt om het verschil tussen twee arrays te bepalen (een oude lijst en een nieuwe lijst). Hiermee kun je bepalen welke elementen zijn toegevoegd en welke zijn verwijderd.
1// Find added and removed items between two arrays
2function diffArrays(oldArr, newArr) {
3 const oldSet = new Set(oldArr);
4 const newSet = new Set(newArr);
5
6 const added = [...newSet].filter(x => !oldSet.has(x));
7 const removed = [...oldSet].filter(x => !newSet.has(x));
8
9 return { added, removed };
10}
11
12const oldList = [1, 2, 3];
13const newList = [2, 3, 4, 5];
14
15console.log(diffArrays(oldList, newList));
16// { added: [4,5], removed: [1] }
- Deze methode is erg handig om verschillen te detecteren in ID-lijsten, taglijsten en vergelijkbare situaties. Het is het eenvoudigst te gebruiken met primitieve waarden.
Verschillen tussen WeakSet en Set (geheugenbeheer)
WeakSet lijkt op Set, maar gebruikt zwakke referenties, waardoor de items kunnen worden opgeruimd door de garbage collector. Het volgende laat het basisgebruik van WeakSet zien.
1// WeakSet basics (objects only, not iterable)
2const ws = new WeakSet();
3let obj = { id: 1 };
4ws.add(obj);
5
6console.log(ws.has(obj)); // true
7
8obj = null; // Now the object is eligible for GC; WeakSet won't prevent collection
WeakSet kan alleen objecten bevatten en kan niet worden geïtereerd. Hieronder vind je voorbeelden van de beperkingen van WeakSet—het bevat alleen objecten en is niet itereerbaar.
1// WeakSet basics (objects only, not iterable)
2const ws = new WeakSet();
3
4// --- Only objects can be added ---
5try {
6 ws.add(1); // number
7} catch (e) {
8 console.log("Error: WeakSet can only store objects. Adding a number is not allowed.");
9}
10
11try {
12 ws.add("text"); // string
13} catch (e) {
14 console.log("Error: WeakSet can only store objects. Adding a string is not allowed.");
15}
16
17// --- WeakSet is not iterable ---
18try {
19 for (const value of ws) {
20 console.log(value);
21 }
22} catch (e) {
23 console.log("Error: WeakSet is not iterable. You cannot use for...of to loop over its elements.");
24}
25
26// --- Cannot convert to array ---
27try {
28 console.log([...ws]);
29} catch (e) {
30 console.log("Error: WeakSet cannot be converted to an array because it does not support iteration.");
31}
32
33// The object becomes eligible for garbage collection
34let obj = { id: 1 };
35ws.add(obj);
36obj = null;WeakSetis handig om tijdelijk het bestaan van objecten bij te houden, maar je kunt zijn elementen niet opsommen of de grootte opvragen.
Prestatie en het kiezen van het juiste gebruiksmoment
Bij het beslissen of je een Set wilt gebruiken, is het belangrijk om de prestatiekenmerken en de aard van je gegevens te begrijpen.
has,addendeletewerken doorgaans met een bijna O(1)-prestatie gemiddeld genomen. Daarom isSetvaak voordeliger dan arrays in scenario's waarbij je vaak controleert op bestaan of duplicaten verwijdert.- Wees voorzichtig als je objecten wilt dedupliceren op basis van hun inhoud (waarden). Omdat
Setvergelijkt op basis van referentie, is het in de praktijk handig om ID's of andere sleutels te gebruiken, of objecten te serialiseren tot primitieve waarden voordat je Sets gebruikt wanneer vergelijking op basis van waarde nodig is. Setis bijzonder nuttig om de code leesbaarder te maken voor kleine tot middelgrote verzamelingen. Aan de andere kant, als je werkt met een zeer groot aantal elementen of vaak converteert tussen arrays en Sets, wordt het aanbevolen om daadwerkelijk te benchmarken en te testen.
Veelvoorkomende valkuilen
Set is handig, maar als je zijn specificaties niet kent, kun je verrast worden door onverwachte gedragingen. Hier zijn een aantal typische aandachtspunten:.
- Objecten worden vergeleken op basis van referentie; zelfs als hun inhoud gelijk is, worden verschillende objecten niet als duplicaten beschouwd.
Setbehoudt de invoegvolgorde, maar je kunt geen elementen op index benaderen zoals bij arrays. Als je toegang op basis van index wilt, zet deSetdan eerst om in een array.WeakSetkan niet worden opgesomd en kan alleen objecten opslaan. Houd er rekening mee dat het toepassingsgebied beperkt is.NaNwordt behandeld als dezelfde waarde, en+0en-0worden niet onderscheiden. Dit komt door de Same-value-zero vergelijkingsregel.
Samenvatting
Set is een handige datastructuur waarmee je verzamelingen van unieke waarden op een intuïtieve manier kunt beheren. Je kunt het gebruiken om duplicaten uit arrays te verwijderen, snelle bestaanchecks uit te voeren, of setoperaties zoals unie en doorsnede te implementeren met simpele en leesbare code.
Daarentegen, omdat objecten op referentie worden vergeleken, zijn extra maatregelen nodig als je gelijkheid op inhoud wilt controleren.
Door deze eigenschappen te begrijpen en ze juist toe te passen, wordt Set een krachtige keuze om de leesbaarheid en het onderhoud van je code te verbeteren.
Je kunt het bovenstaande artikel volgen met Visual Studio Code op ons YouTube-kanaal. Bekijk ook het YouTube-kanaal.