# Unieke data

Sets, Maps, WeakMaps, en Symbols hebben gemeenschappelijk dat ze allemaal worden gebruikt als gegevensstructuren in programmeertalen en dat ze gericht zijn op het organiseren, opslaan en benaderen van gegevens. Hier zijn enkele gemeenschappelijke kenmerken:

  • Gegevensorganisatie: Ze bieden een georganiseerde manier om gegevens op te slaan en te structureren.
  • Uniekheid: Sets, Maps en Symbols leggen nadruk op uniciteit. In een Set zijn alle elementen uniek, in een Map moeten de sleutels uniek zijn, en Symbols zijn unieke identificatoren
  • Flexibiliteit: Ze bieden flexibele manieren om met gegevens om te gaan. Sets kunnen worden gebruikt voor unieke verzamelingen, Maps voor key-value-paren, WeakMaps voor gegevens met zwakke referenties, en Symbols als unieke identificatoren.
  • Objectgerichtheid: Ze zijn allemaal objectgericht en kunnen vaak worden gebruikt in combinatie met andere objectgerichte principes in programmeertalen.

Hoewel ze gemeenschappelijke kenmerken hebben, hebben ze ook specifieke toepassingen en gebruiksscenario’s waarvoor ze het meest geschikt zijn. Bijvoorbeeld, Sets zijn handig voor het beheren van unieke waarden, Maps voor key-value-paren, WeakMaps voor situaties waarin zwakke referenties belangrijk zijn, en Symbols voor unieke eigenschappenidentificatie.

# Symbols

Een Symbol is een ingebouwd (Eng. built-in) object dat een unieke Symbol sleutel bevat. De eigenschappen van een regulier object is een string of van het type symbol.

# Gebruik

Een value van dit type kan aangemaakt worden d.m.v. de Symbol() constructor:

let id = Symbol();
1

Bij aanmaak kunnen we ook een extra omschrijving of naam geven aan dit symbol:

let id = Symbol("unique identification");
1

Symbols zijn uniek ook als we verschillende symbols aanmaken met dezelfde omschrijving, ze bevatten verschillende waarden.

let id1 = Symbol("unique identification");
let id2 = Symbol("unique identification");
console.log(id1 === id2); // Returns false
1
2
3

Symbols worden niet automatisch geconverteerd naar een string. Het resultaat is de waarde undefined of een TypeError: Cannot convert a Symbol value to a string afhankelijk van de browser-engine. Om een symbol te converteren naar een string gebruiken we de toString methode. We kunnen daarnaast ook de omschrijving of naam van een symbol opvragen via de description eigenschap.

let id = Symbol("unique identification");
console.log(id); // Returns undefined
console.log(id.toString()); // Returns "Symbol(unique identification)"
console.log(id.description); // Returns "unique identification"
1
2
3
4

Symbols kunnen niet opgesomd (Eng. enumerated) worden. Dit betekent dat ze niet inbegrepen zijn in een for...of of een for...in lus om hiermee de eigenschappen van een object te doorlopen. Symbols maken eveneens geen deel uit van het resultaat Object.keys() en Object.getOwnProperty(). Om de symbols van een object op te vragen kunnen we gebruik maken van Object.getOwnPropertySymbols().

const cats = {};
const f = Symbol("Frodo");
const c = Symbol("Corneel");
cats[f] = {
  name: "Frodo",
  age: 17,
};
cats[c] = {
  name: "Corneel",
  age: 2,
};

console.log(Object.getOwnPropertySymbols(cats)); // Array [ Symbol("Frodo"), Symbol("Corneel") ]
1
2
3
4
5
6
7
8
9
10
11
12
13

# Toepassingen

# Symbols als unieke waarden

let statuses = {
  OPEN: Symbol("Open"),
  IN_PROGRESS: Symbol("In progress"),
  COMPLETED: Symbol("Completed"),
  HOLD: Symbol("On hold"),
  CANCELED: Symbol("Canceled"),
};

const task = {
  state: statuses.OPEN,
  setState(state) {
    this.state = state;
  },
};
task.setState(statuses.COMPLETED);
console.log(task); // Returns Object { state: Symbol("Completed"), setState: setState(state) }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# Symbol als een unieke eigenschap van een object

const state = Symbol("State");

const task = {
  [state]: statuses.Open,
};
task[state] = statuses.COMPLETED;
console.log(task);
1
2
3
4
5
6
7

# Set

Met het Set object kunnen we een verzameling van unieke waarden bewaren van eender welk type (primitieve waarden en object referenties). Een waarde kan maar een keer voorkomen (Eng. may only occure once).

Itereren over de waarden uit een Set object kunnen we realiseren via het for...of statement of via forEach methode uit het Set object.

Met de has methode uit het Set object kunnen we nagaan of een waarde aanwezig is in de verzameling. Deze methode is sneller in vergelijking met de include methode uit het Array object.

# Gebruik

const mySet = new Set();
console.log(mySet);
mySet.add(1);
mySet.add(true);
mySet.add("pgm");
console.log(mySet.size); // returns 3

for (let value of mySet) {
  console.log(value);
}

mySet.forEach((value) => {
  console.log(value);
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14

Unieke waarden:

const mySet = new Set();
mySet.add(1);
mySet.add(1);
mySet.add("pgm");
mySet.add("Pgm");
const obj = { firstName: "Philippe" };
mySet.add(obj);
console.log(mySet.size); // returns 4

console.log(mySet.has("pgm")); // Returns true
console.log(mySet.has(obj)); // Returns true
console.log(mySet.has({ firstName: "Philippe" })); // Returns false (it's no identical reference)

console.log(mySet.delete("pGm")); // Returns false

console.log(mySet.delete({ firstName: "Philippe" })); // Returns false

console.log(mySet.delete(obj)); // Returns true

console.log(mySet.size);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# Array naar Set en omgekeerd

const values = [1, 1, 2, 2, 3, 4, 5, 5];
const mySet = new Set(values);
const uniqueValues = [...mySet];
console.log(uniqueValues); // Returns [1, 2, 3, 4, 5];
1
2
3
4

Referentie van een object is uniek ongeacht de gelijkheid van eigenschappen en corresponderende waarden:

const values = [
  1,
  1,
  2,
  { firstName: "Philippe" },
  3,
  { firstName: "Philippe" },
  5,
  5,
];
const mySet = new Set(values);
const uniqueValues = [...mySet];
console.log(uniqueValues); // Returns [1, 2, { firstName: 'Philippe' }, 3, { firstName: 'Philippe' }, 5];
1
2
3
4
5
6
7
8
9
10
11
12
13

# String naar Set en omgekeerd

const word = `Programming`;
const mySet = new Set(word);

let output = "";
for (let [value, index] of mySet.entries()) {
  output += index;
}
console.log(output); // Returns Programin
1
2
3
4
5
6
7
8

value en index hebben dezelfde waarde. De waarden zijn hoofdlettergevoelig dat betekent dat bv. F niet gelijk is aan f.

# Unie van twee Set objecten

function unionOfTwoSets(set1, set2) {
  const union = new Set(set1);
  for (let value of set2) {
    if (!union.has(value)) {
      union.add(value);
    }
  }
  return union;
}

const setA = new Set([1, 2, 3, 4, 5]);
const setB = new Set([4, 5, 6, 7, 8]);
const union = unionOfTwoSets(setA, setB);
console.log([...union]); // Result [1,2,3,4,5,6,7,8]
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# Verschil tussen twee Set objecten

function differenceBetweenTwoSets(set1, set2) {
  const difference = new Set(set1);
  for (let value of set2) {
    if (difference.has(value)) {
      difference.delete(value);
    } else {
      difference.add(value);
    }
  }
  return difference;
}

const setA = new Set([1, 2, 3, 4, 5]);
const setB = new Set([4, 5, 6, 7, 8]);
const difference = differenceBetweenTwoSets(setA, setB);
console.log([...difference]); // Result [1,2,3,6,7,8]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# WeakSet

Met het WeakSet object kunnen we een verzameling van unieke waarden bewaren van het object type. Een waarde kan maar een keer voorkomen. Het is kortom een collectie van objecten. Een WeakSet is weak. De referentie naar objecten worden zwak (Eng. weakly) vastgehouden. Wanneer de referenties naar deze objecten enkel bestaan in de WeakSet, dan kunnen deze verwijderd geworden uit het geheugen (Eng. garbage collected). Een WeakSet is niet doorloopbaar.

# Map

Een Map object bevat een verzameling van key-value pairs. Net zoals een Set object kunnen de waarden (Eng. values) en de sleutels (Eng. keys) van eender welk type (primitieve waarden en object referenties) zijn.

Een Object is zeer gelijkaardig met een Map object, beiden maken gebruik van key-value pairs, via een key kunnen we de waarde ervan opvragen, wijzigen en verwijderen. Daarnaast kunnen we ook nagaan of een sleutel al dan niet aanwezig is. Een Map object heeft geen standaard eigenschappen of sleutels. Een Object darentegen heeft dat wel. De sleutels in een Object moet een String of een Symbol zijn. Het aantal items is in een Map object eenvoudig op te vragen via de size eigenschap. In een Object moeten we dit zelf bepalen. JSON.stringify() en JSON.parse() is niet rechtstreeks toepasbaar op een Map object. Een Map object is itereerbaar out-of-the-box, een Object is dat niet.

# Gebruik

const students = new Map();
students.set(6805242, { firstName: "Evelien" });
students.set(6670583, { firstName: "Olivier" });
students.set(6012895, { firstName: "Adriaan" });
console.log(students.size);
let student = students.get(6805242);
console.log(student);
students.delete(6670583);
student = students.get(6670583);
console.log(student); // Returns undefined
console.log(students.has(6670583)); // Returns false
1
2
3
4
5
6
7
8
9
10
11

Ophalen en doorlopen van key / value pairs:

const students = new Map();
students.set(6805242, { firstName: "Evelien" });
students.set(6670583, { firstName: "Olivier" });
students.set(6012895, { firstName: "Adriaan" });
let student = students.get(6012895);
console.log(student);

for (let [key, value] of students) {
  console.log(`Student with key ${key} and value ${JSON.stringify(value)}`); // Returns Student with key 6805242 and value {'firstName':'Evelien'}"
}

students.forEach((value, key) => {
  console.log(`Student with key ${key} and value ${JSON.stringify(value)}`); // Returns Student with key 6805242 and value {'firstName':'Evelien'}"
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# Array naar Map en omgekeerd

const originalArray = [
  [6805242, "Evelien"],
  [6670583, "Olivier"],
  [6012895, "Adriaan"],
];

const students = new Map(originalArray);
console.log(students);

let newArray = Array.from(students);
console.log(newArray); // Returns [[6805242, "Evelien"], [6670583, "Olivier"], [6012895, "Adriaan"]]

newArray = [...students];
console.log(newArray); // Returns [[6805242, "Evelien"], [6670583, "Olivier"], [6012895, "Adriaan"]]

const studentsCloned = new Map(students);
console.log(studentsCloned === students); // Returns false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# Unie van twee Map objecten

const first = new Map([
  [1, "one"],
  [2, "two"],
  [3, "three"],
]);

const second = new Map([
  [1, "uno"],
  [2, "dos"],
]);

const merged = new Map([...first, ...second]);

merged.forEach((value, key) => {
  console.log(`Element with key ${key} and value ${JSON.stringify(value)}`); //Returns "Element with key 1 and value 'uno'"
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
© 2025 Arteveldehogeschool Laatst bijgewerkt: 18/11/2023 15:07:08