Skip to content

Commit 5c9009e

Browse files
authored
Merge pull request #239 from Dorin-David/Article/weakmap-weakset
Article/weakmap weakset
2 parents 1d1858e + 2bc73c3 commit 5c9009e

File tree

6 files changed

+70
-59
lines changed

6 files changed

+70
-59
lines changed

1-js/05-data-types/07-map-set/02-filter-anagrams/solution.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ cheaters, hectares, teachers -> aceehrst
99
...
1010
```
1111

12-
Utilizzeremo la variante con le lettere ordite come chiave di una map per memorizzare un solo valore:
12+
Utilizzeremo la variante con le lettere ordinate come chiave di una map per memorizzare un solo valore:
1313

1414
```js run
1515
function aclean(arr) {
1616
let map = new Map();
1717

1818
for (let word of arr) {
19-
// split the word by letters, sort them and join back
19+
// dividi la parola in lettere, ordinale e ricongiungile
2020
*!*
2121
let sorted = word.toLowerCase().split('').sort().join(''); // (*)
2222
*/!*
@@ -53,7 +53,7 @@ map.set(sorted, word);
5353

5454
Se abbiamo già incontrato una parola con la stessa forma, la sovrascriviamo con quella nuova, in modo tale da avere sempre una sola occorrenza all'interno della map.
5555

56-
Alla fine `Array.from(map.values())` prende un iteratore sui valori di map (non abbiamo bisogno delle chiavi nel risultato) e ne ritorna un array.
56+
Alla fine `Array.from(map.values())` prende un iteratore sui valori di `map` (non abbiamo bisogno delle chiavi nel risultato) e ne ritorna un array.
5757

5858
Qui potremmo anche utilizzare un normale oggetto piuttosto di `Map`, poiché le chiavi sono stringhe.
5959

1-js/05-data-types/07-map-set/03-iterable-keys/task.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ importance: 5
44

55
# Chiavi iterabili
66

7-
Vorremmo avere un array di `map.keys()` in una variabile, quindi poterle applicare un metodo specifico degli arrays, ad esempio `.push`.
7+
Vorremmo avere un array di `map.keys()` in una variabile, quindi potergli applicare un metodo specifico degli arrays, ad esempio `.push`.
88

99
Ma c'è un problema:
1010

1-js/05-data-types/07-map-set/article.md

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33

44
Finora abbiamo appreso le nozioni di base riguardo le seguenti strutture dati:
55

6-
- Oggetti, per la memorizzazione di collezioni identificate da chiave.
6+
- Oggetti, per la memorizzazione di collezioni identificate da una chiave.
77
- Array, per la memorizzazione di collezioni ordinate.
88

9-
Queste non sono però sufficienti nella vita reale. Per esistono ulteriori strutture dati come `Map` e `Set`.
9+
Queste però non sono sufficienti. Esistono ulteriori strutture dati, come `Map` e `Set`.
1010

1111
## Map
1212

@@ -42,7 +42,7 @@ alert( map.size ); // 3
4242
Come abbiamo potuto osservare, a differenza degli oggetti, le chiavi non vengono convertite a stringa. Sono quindi ammesse chiavi di qualunque tipo.
4343

4444
```smart header="`map[key]` non è il modo corretto di utilizzare una `Map`"
45-
Anche se `map[key]` funziona, ad esempio possiamo impostare `map[key] = 2`, equivale a trattare una `map` come un oggetto semplice, con tutte le limitazioni correlate agli oggetti.
45+
Anche se `map[key]` funziona, ad esempio possiamo impostare `map[key] = 2`, questo equivale a trattare`map` come un oggetto semplice, con tutte le limitazioni correlate.
4646

4747
Quindi dovremmo utilizzare i metodi dedicati a `map`: `set`, `get` e gli altri.
4848
```
@@ -54,7 +54,7 @@ Ad esempio:
5454
```js run
5555
let john = { name: "John" };
5656
57-
// per ogni utente, memorizziamo il contatore di visite
57+
// per ogni utente, memorizziamo il contatore delle visite
5858
let visitsCountMap = new Map();
5959
6060
// john è la chiave
@@ -63,7 +63,7 @@ visitsCountMap.set(john, 123);
6363
alert( visitsCountMap.get(john) ); // 123
6464
```
6565

66-
Il fatto di poter utilizzare oggetti come chiave è una delle caratteristiche più importanti fornite dalla struttura dati `Map`. Per chiavi di tipo string, un normale `Object` può andare bene, ma non vale lo stesso per chiavi di tipo oggetto.
66+
Il fatto di poter utilizzare oggetti come chiavi è una delle caratteristiche più importanti fornite dalla struttura dati `Map`. In un normale `Object` una chiave di tipo stringa può andare bene, ma non vale lo stesso per le chiavi di tipo oggetto.
6767

6868
Proviamo:
6969

@@ -80,16 +80,16 @@ alert( visitsCountObj["[object Object]"] ); // 123
8080
*/!*
8181
```
8282

83-
Dal momento che `visitsCountObj` è un oggetto, converte tutte le chiavi, come `john` e `ben` a stringhe, quindi otteniamo la chiave `"[object Object]"`. Senza dubbio non ciò che ci aspettavamo.
83+
Dal momento che `visitsCountObj` è un oggetto, converte tutte le chiavi, come `john` e `ben`, a stringhe, quindi otteniamo la chiave `"[object Object]"`. Senza dubbio non ciò che ci aspettavamo.
8484

85-
```smart header="How `Map` confronta le chiavi"
85+
```smart header="Come `Map` confronta le chiavi"
8686
Per verificare l'equivalenza delle chiavi, `Map`utilizza l'algoritmo [SameValueZero](https://tc39.github.io/ecma262/#sec-samevaluezero). E' quasi la stessa cosa dell'uguaglianza stretta `===`, con la differenza che `NaN` viene considerato uguale a `NaN`. Quindi anche `NaN` può essere utilizzato come chiave.
8787

88-
L'algoritmo di confronto non può essere ne cambiato ne modificato.
88+
L'algoritmo di confronto non può essere cambiato modificato.
8989
```
9090
9191
````smart header="concatenamento"
92-
Ogni chiamata a `map.set` la mappa stessa, quindi possiamo concatenare le chiamate:
92+
Ogni chiamata a `map.set` ritorna la mappa stessa, quindi possiamo concatenare le chiamate:
9393
9494
```js
9595
map.set('1', 'str1')
@@ -103,8 +103,8 @@ map.set('1', 'str1')
103103
Per iterare attraverso gli elementi di `Map`, esistono 3 metodi:
104104
105105
- `map.keys()` -- ritorna un oggetto per iterare sulle chiavi,
106-
- `map.values()` -- ritorna un oggetto per iterar sui valori,
107-
- `map.entries()` -- ritorna un oggetto per iterare sulle voci `[key, value]`, ed è il metodo utilizzato di default nel ciclo `for..of`.
106+
- `map.values()` -- ritorna un oggetto per iterare sui valori,
107+
- `map.entries()` -- ritorna un oggetto per iterare sulle coppie `[key, value]`, ed è il metodo utilizzato di default nel ciclo `for..of`.
108108
109109
Ad esempio:
110110
@@ -146,7 +146,7 @@ recipeMap.forEach( (value, key, map) => {
146146
147147
## Object.entries: Map da Object
148148
149-
Durante la fase di creazione di una `Map`, possiamo passargli un array (o qualsiasi altra struttura dati iterabile) con coppie chiave/valore per inizializzare la `Map`, come nel seguente esempio:
149+
Durante la fase di creazione di una `Map`, possiamo passarle un array (o qualsiasi altra struttura dati iterabile) con coppie chiave/valore per inizializzare la `Map`, come nel seguente esempio:
150150
151151
```js run
152152
// array di coppie [chiave, valore]
@@ -161,7 +161,7 @@ alert( map.get('1') ); // str1
161161
162162
Se abbiamo un semplice oggetto, e vogliamo utilizzarlo per creare una `Map`, possiamo utilizzare un metodo integrato degli oggetti [Object.entries(obj)](mdn:js/Object/entries) il quale ritorna un array di coppie chiave/valore nello stesso formato.
163163
164-
Quindi possiamo creare una `Map` da un oggetto come questo:
164+
Quindi possiamo creare una `Map` da un oggetto, così:
165165
166166
```js run
167167
let obj = {
@@ -192,14 +192,14 @@ let prices = Object.fromEntries([
192192
['meat', 4]
193193
]);
194194
195-
// now prices = { banana: 1, orange: 2, meat: 4 }
195+
// ora prices = { banana: 1, orange: 2, meat: 4 }
196196
197197
alert(prices.orange); // 2
198198
```
199199
200200
Possiamo utilizzare il metodo `Object.fromEntries` per ottenere un oggetto partendo da una `Map`.
201201
202-
Ad esempio memorizziamo i dati in una `Map`, ma abbiamo bisogno di passarli ad un codice di terze parti che si aspetta un oggetto.
202+
Ad esempio, memorizziamo i dati in una `Map`, ma abbiamo bisogno di passarla ad un codice di terze parti che si aspetta un oggetto.
203203
204204
Quindi:
205205
@@ -221,7 +221,7 @@ alert(obj.orange); // 2
221221
222222
Una chiamata a `map.entries()` ritorna un array di coppie chiave/valore, esattamente nel formato richiesto da `Object.fromEntries`.
223223
224-
Possiamo rendere la rica `(*)` ancora più corta:
224+
Possiamo rendere la riga `(*)` ancora più corta:
225225
```js
226226
let obj = Object.fromEntries(map); // omettendo .entries()
227227
```
@@ -235,15 +235,15 @@ Un `Set` è un tipo di collezione speciale - "set di valori" (senza chiavi), dov
235235
I suoi metodi principali sono:
236236
237237
- `new Set(iterable)` -- crea il set, e se gli viene fornito un oggetto `iterabile` (solitamente un array), ne copia i valori nel set.
238-
- `set.add(value)` -- aggiunge un valore, e ritorna il set.
238+
- `set.add(value)` -- aggiunge un valore, ritorna il set.
239239
- `set.delete(value)` -- rimuove il valore, ritorna `true` se `value` esiste, altrimenti `false`.
240240
- `set.has(value)` -- ritorna `true` se il valore esiste nel set, altrimenti `false`.
241241
- `set.clear()` -- rimuove tutti i valori dal set.
242-
- `set.size` -- ritorna la dimensione del set, ovvero il numero di valori contenuti.
242+
- `set.size` -- ritorna il numero dei valori contenuti.
243243
244-
La principale caratteristica dei set è che ripetute chiamate di `set.add(value)` con lo stesso valore, non fanno nulla. Questo è il motivo per cui ogni valore può comparire una sola volta in un `Set`.
244+
La principale caratteristica dei set è che ripetute chiamate di `set.add(value)` con lo stesso valore non fanno nulla. Questo è il motivo per cui in un `Set` ogni valore può comparire una sola volta.
245245
246-
Ad esempio, abbiamo diversi arrivi di visitatori, e vorremmo ricordarli tutti. Ma visite ripetute dello stesso non dovrebbe portare a duplicati. Un visitatore deve essere conteggiato una volta sola.
246+
Ad esempio, abbiamo diversi arrivi di visitatori, e vorremmo ricordarli tutti. Ma visite ripetute dello stesso utente non dovrebbe portare a duplicati. Un visitatore deve essere conteggiato una volta sola.
247247
248248
`Set` è esattamente la struttura dati che fa al caso nostro:
249249
@@ -269,7 +269,7 @@ for (let user of set) {
269269
}
270270
```
271271
272-
L'alternativa a `Set` potrebbe essere un array di visitatori, aggiungendo del codice per verificare ogni inserimento ed evitare i duplicati, utilizzando [arr.find](mdn:js/Array/find). Ma le performance sarebbero di molto peggiori, perché questo metodo attraversa tutto l'array per verificare ogni elemento. `Set` è ottimizzato internamente per controllo di unicità.
272+
L'alternativa a `Set` potrebbe essere un array di visitatori, e un codice per verificare ogni inserimento ed evitare duplicati, utilizzando [arr.find](mdn:js/Array/find). Ma la performance sarebbe molto inferiore, perché questo metodo attraversa tutto l'array per verificare ogni elemento. `Set` è ottimizzato internamente per il controllo di unicità.
273273
274274
## Iterare un Set
275275
@@ -286,36 +286,36 @@ set.forEach((value, valueAgain, set) => {
286286
});
287287
```
288288
289-
Da notare una cosa divertente. La funzione di callback fornita al `forEach` ha 3 argomenti: un `value`, poi *lo stesso valore* `valueAgain`, e poi l'oggetto su cui iterare. Proprio cosi, lo stesso valore appare due volte nella lista degli argomenti.
289+
Da notare una cosa divertente. La funzione callback fornita a `forEach` ha 3 argomenti: un `value`, poi *lo stesso valore* `valueAgain`, e poi l'oggetto riferito da `this`. Proprio così, lo stesso valore appare due volte nella lista degli argomenti.
290290
291-
Questo accade per questioni di compatibilità con `Map` in cui la funzione callback fornita al `forEach` possiede tre argomenti. E' un po strano. Però in alcuni casi può aiutare rimpiazzare `Map` con `Set`, e vice versa.
291+
Questo accade per questioni di compatibilità con `Map`, in cui la funzione callback fornita al `forEach` possiede tre argomenti. E' un po' strano, ma in alcuni casi può aiutare rimpiazzare `Map` con `Set`, e vice versa.
292292
293-
Sono supportati anche i metodi di iterazione offerti da `Map`:
293+
Sono supportati anche i metodi di iterazione di `Map`:
294294
295295
- `set.keys()` -- ritorna un oggetto per iterare sui valori,
296296
- `set.values()` -- lo stesso di `set.keys()`, per compatibilità con `Map`,
297297
- `set.entries()` -- ritorna un oggetto per iterare sulle voci `[value, value]`, esiste per compatibilità con `Map`.
298298
299299
## Riepilogo
300300
301-
`Map` -- è una collezione di valori identificati da chiave.
301+
`Map` è una collezione di valori identificati da chiave.
302302
303303
Metodi e proprietà:
304304
305305
- `new Map([iterable])` -- crea la mappa, accetta un oggetto iterabile (opzionale, e.g. array) di coppie `[key,value]` per l'inizializzazione.
306306
- `map.set(key, value)` -- memorizza il valore con la chiave fornita.
307-
- `map.get(key)` -- ritorna il valore associata alla chiave, `undefined` se la `key` non è presente nella `Map`.
307+
- `map.get(key)` -- ritorna il valore associato alla chiave, `undefined` se la `key` non è presente nella `Map`.
308308
- `map.has(key)` -- ritorna `true` se la `key` esiste, `false` altrimenti.
309309
- `map.delete(key)` -- rimuove il valore associato alla chiave.
310310
- `map.clear()` -- rimuove ogni elemento dalla mappa.
311-
- `map.size` -- ritorna il numero di elementi contenuti nella map.
311+
- `map.size` -- ritorna il numero di elementi contenuti nella `map`.
312312
313313
Le differenze da un `Object` standard:
314314
315315
- Le chiavi possono essere di qualsiasi tipo, anche oggetti.
316316
- Possiede metodi aggiuntivi, come la proprietà `size`.
317317
318-
`Set` -- è una collezione di valori unici.
318+
`Set` è una collezione di valori unici.
319319
320320
Metodi e proprietà:
321321
@@ -324,6 +324,6 @@ Metodi e proprietà:
324324
- `set.delete(value)` -- rimuove il valore, ritorna `true` se `value` esiste, `false` altrimenti.
325325
- `set.has(value)` -- ritorna `true` se il valore esiste nel set, `false` altrimenti.
326326
- `set.clear()` -- rimuove tutti i valori dal set.
327-
- `set.size` -- ritorna la dimensione del set, ovvero il numero di valori contenuti.
327+
- `set.size` -- ritorna il numero di valori contenuti.
328328
329-
L'iterazione su `Map` e `Set` segue sempre l'ordine di inserimento, quindi posso essere definite delle collezioni ordinate, non è però possibile riordinare gli elementi oppure ottenere un valore tramite il suo indice.
329+
L'iterazione su `Map` e `Set` segue sempre l'ordine di inserimento, quindi possono essere definite delle collezioni ordinate; non è però possibile riordinare gli elementi oppure ottenere un valore tramite il suo indice.
Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,47 @@
1+
Memorizziamo i messaggi letti in `WeakSet`:
2+
3+
```js run
4+
let messages = [
5+
{text: "Hello", from: "John"},
16
{text: "How goes?", from: "John"},
27
{text: "See you soon", from: "Alice"}
38
];
49

510
let readMessages = new WeakSet();
611

7-
// two messages have been read
12+
//due messaggi sono stati letti
813
readMessages.add(messages[0]);
914
readMessages.add(messages[1]);
10-
// readMessages has 2 elements
15+
// readMessages ha due elementi
1116

12-
// ...let's read the first message again!
17+
//...leggiamo nuovamente il primo messaggio!
1318
readMessages.add(messages[0]);
14-
// readMessages still has 2 unique elements
19+
// readMessages ha 2 elementi unici
1520

16-
// answer: was the message[0] read?
21+
//risposta: message[0] è stato letto?
1722
alert("Read message 0: " + readMessages.has(messages[0])); // true
1823

1924
messages.shift();
20-
// now readMessages has 1 element (technically memory may be cleaned later)
25+
// ora readMessages ha un elemento (tecnicamente la memoria potrebbe essere ripulita dopo)
2126
```
2227

2328
La struttura `WeakSet` consente di memorizzare un insieme di messaggi e di verificare molto rapidamente la presenza di un dato messaggio.
2429

2530
Viene ripulita automaticamente. Il lato negativo è che non possiamo eseguire iterazioni. Non possiamo ottenere direttamente "tutti i messaggi letti". Ma possiamo farlo iterando su tutti i messaggi e filtrando tutti quelli che sono presenti nel set.
2631

27-
P.S. Aggiungere una proprietà ad ogni messaggio potrebbe essere pericoloso, se questo oggetto viene gestito dal codice di un'altra persona; per evitare conflitti possiamo utilizzare un *symbol*.
32+
Another, different solution could be to add a property like `message.isRead=true` to a message after it's read. As messages objects are managed by another code, that's generally discouraged, but we can use a symbolic property to avoid conflicts.
33+
34+
Un'altra soluzione potrebbe essere aggiungere una proprietà come `message.isRead=true`, ma farlo potrebbe essere pericoloso, se questo oggetto viene gestito dal codice di un'altra persona; per evitare conflitti possiamo utilizzare un *symbol*.
2835

2936
Come qui:
3037
```js
31-
// the symbolic property is only known to our code
38+
//la proprietà simbolica è visibile solo al nostro codice
3239
let isRead = Symbol("isRead");
3340
messages[0][isRead] = true;
3441
```
3542

36-
Ora anche se qualcun'altro utilizza `for..in` per avere accesso a tutte le proprietà di messagge, la nostra etichetta sarà segreta.
43+
Ora anche se qualcun altro utilizza `for..in` per avere accesso a tutte le proprietà di messagge, la nostra proprietà sarà segreta.
44+
45+
46+
Although symbols allow to lower the probability of problems, using `WeakSet` is better from the architectural point of view.
47+
Sebbene i simboli permettano una minore probabilità di problemi, utilizzare `weakSet` è meglio da un punto di vista architetturale.

1-js/05-data-types/08-weakmap-weakset/02-recipients-when-read/task.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ let messages = [
1616

1717
Ora la domanda è: quale struttura di dati converrebbe utilizzare per memorizzare l'informazione: "quando è stato letto il messaggio?".
1818

19-
Nel compito precedente la necessità era semplicemente di memorizzare la lettura del messaggio. Ora abbiamo bisogno di memorizzare anche la data, anche in questo caso, se il messaggio viene eliminato questa dovrebbe sparire.
19+
Nel compito precedente la necessità era semplicemente di memorizzare la lettura del messaggio. Ora abbiamo bisogno di memorizzare anche la data; anche in questo caso, se il messaggio viene eliminato questa dovrebbe sparire.

0 commit comments

Comments
 (0)