Objet `Set`
Cet article explique l'objet Set.
Nous expliquerons l'objet Set à l'aide d'exemples pratiques.
YouTube Video
Objet Set
Set est un objet natif utilisé pour gérer des ensembles de valeurs uniques, sans doublons. Il permet d'éliminer les doublons et de vérifier l'existence d'une valeur plus simplement qu'avec les tableaux, et facilite la mise en œuvre des opérations ensemblistes, telles que l'union et l'intersection.
Notions de base : création et utilisation des Sets
Tout d'abord, voyons comment créer un Set, ajouter et supprimer des éléments, vérifier leur existence et obtenir sa taille.
Voici un exemple de base qui crée un nouveau Set et montre les méthodes add, has, delete et size.
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]
- Comme le montre ce code,
Setsupprime automatiquement les valeurs primitives en double, et vous pouvez obtenir le nombre d’éléments grâce àsize.
Méthodes d'itération
Set est itérable, vous pouvez donc le parcourir en utilisant for...of ou forEach. L'ordre correspond à l'ordre d'insertion.
Voici des exemples d'utilisation de for...of et forEach.
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});- La signature de rappel pour
forEachestvalue, value, set(pour la compatibilité avec Map), mais en pratique, on n'utilise généralement que le premier argumentvalue.
Conversion entre tableaux et Sets (utile pour supprimer les doublons)
Nous présentons ici une technique simple pour supprimer les doublons d'un tableau et comment convertir un Set en tableau.
Voici un exemple de suppression des doublons d'un tableau en le passant dans un Set.
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]
- Ce schéma est rapide et concis, il est donc couramment utilisé pour enlever les doublons d'un tableau. C'est particulièrement efficace pour les valeurs primitives.
Objets et gestion des références
Les objets dans un Set sont comparés par référence ; ainsi, différentes instances avec le même contenu sont considérées comme des éléments distincts.
Le code suivant montre ce qui se passe lorsque vous ajoutez des objets dans un 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)
- La détection des doublons pour les objets se fait par identité de référence ; donc, si vous souhaitez dédupliquer selon le contenu uniquement, il faudra sérialiser ou traiter ces objets différemment.
Valeurs spéciales : gestion de NaN et de -0/+0
Set utilise la règle de comparaison Same-value-zero pour déterminer l'égalité des valeurs. Cette méthode de comparaison a les caractéristiques suivantes concernant les nombres :.
NaNest considéré comme égal àNaN.+0et-0ne sont pas distingués et sont traités comme la même valeur.
Ainsi, lorsque vous ajoutez ces valeurs à un Set, le comportement suivant se produit :.
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)
- Dans une comparaison normale (
NaN === NaN), cela retournefalse, mais dans unSet, toutes les valeursNaNsont considérées comme « la même valeur ». - +0 et -0 peuvent être distingués mathématiquement, mais dans un
Set, ils sont simplement traités comme0. - En conséquence, une seule valeur
NaNet une seule valeur0restent dans leSet. - La règle de comparaison de
Setest similaire à celle deObject.is, mais pas exactement identique.Object.is(+0, -0)renvoiefalse, mais dans unSet, ils sont considérés comme identiques. Merci de prendre note de cette différence.
Utilitaire courant : opérations sur les ensembles (union, intersection, différence)
Les opérations ensemblistes peuvent être exprimées plus clairement en utilisant Set. Voici des exemples courants d'implémentation.
Voici des exemples de fonctions pour union, intersection et 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]
- Les opérations ensemblistes peuvent être écrites facilement en utilisant des filtres avec la combinaison de
Setet de tableaux. Lors du traitement de grands ensembles de données, la performance O(1) dehasrend les opérations plus rapides.
Exemple pratique : trouver la différence entre deux tableaux (détection des éléments ajoutés/supprimés)
L'exemple suivant montre comment utiliser un Set pour trouver la différence entre deux tableaux (une ancienne liste et une nouvelle liste). Cela permet d'identifier quels éléments ont été ajoutés et lesquels ont été supprimés.
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] }
- Cette méthode est très pratique pour détecter les différences dans des listes d'identifiants, des listes de tags, etc. Il est plus simple de l'utiliser avec des valeurs primitives.
Différences entre WeakSet et Set (gestion de la mémoire)
WeakSet est similaire à Set, mais il utilise des références faibles, ce qui permet à ses éléments d’être collectés par le ramasse-miettes. Voici quelques exemples d'utilisation basique de WeakSet.
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 ne peut contenir que des objets et ne peut pas être itéré. Voici des exemples des contraintes de WeakSet : il ne contient que des objets et ne peut pas être itéré.
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;WeakSetest utile pour suivre temporairement la présence d'objets, mais vous ne pouvez pas énumérer ses éléments ni obtenir sa taille.
Performance et choix d'utilisation
Lorsque vous décidez d'utiliser ou non un Set, il est important de comprendre ses caractéristiques de performance et la nature de vos données.
has,addetdeletefonctionnent généralement avec une performance quasi O(1) en moyenne. Ainsi, dans les situations où l'on vérifie souvent l'existence ou où l'on enlève des doublons,Setest souvent plus avantageux que les tableaux.- Faites attention si vous souhaitez dédupliquer des objets selon leurs contenus (valeurs). Puisque
Setcompare par référence, une méthode pratique consiste à utiliser des IDs ou autres clés, ou à sérialiser les objets en valeurs primitives avant de les utiliser dans un Set lorsque la comparaison sur les valeurs est nécessaire. Setest particulièrement utile pour améliorer la lisibilité du code pour les collections de petite ou moyenne taille. En revanche, si vous gérez un très grand nombre d'éléments ou si vous convertissez fréquemment entre tableaux et Sets, il est recommandé de réaliser des benchmarks et des tests concrets.
Pièges courants
Set est pratique, mais si vous n'êtes pas conscient de ses spécifications, vous pourriez être surpris par des comportements inattendus. Voici quelques points typiques auxquels il faut faire attention :.
- Les objets sont comparés par référence, donc même si leur contenu est identique, des objets différents ne seront pas considérés comme des doublons.
Setmaintient l'ordre d'insertion, mais vous ne pouvez pas accéder aux éléments par index comme dans un tableau. Si vous souhaitez accéder par index, convertissez d'abord leSeten tableau.WeakSetne peut pas être énuméré et ne peut contenir que des objets. Notez que son champ d'application est limité.NaNest traité comme la même valeur, et+0et-0ne sont pas distingués. Cela est dû à la règle de comparaison Same-value-zero.
Résumé
Set est une structure de données pratique qui permet de manipuler intuitivement des collections de valeurs uniques. Vous pouvez l'utiliser pour supprimer les doublons d'un tableau, effectuer des vérifications rapides d'existence ou implémenter des opérations ensemblistes comme l'union et l'intersection avec un code simple et lisible.
En revanche, puisque les objets sont comparés par référence, des mesures supplémentaires sont nécessaires si vous souhaitez comparer selon leur contenu.
En comprenant ces caractéristiques et en les utilisant à bon escient, Set devient un choix puissant pour améliorer la lisibilité et la maintenabilité du code.
Vous pouvez suivre l'article ci-dessus avec Visual Studio Code sur notre chaîne YouTube. Veuillez également consulter la chaîne YouTube.