You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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:
13
13
14
14
```js run
15
15
functionaclean(arr) {
16
16
let map =newMap();
17
17
18
18
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
20
20
*!*
21
21
let sorted =word.toLowerCase().split('').sort().join(''); // (*)
22
22
*/!*
@@ -53,7 +53,7 @@ map.set(sorted, word);
53
53
54
54
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.
55
55
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.
57
57
58
58
Qui potremmo anche utilizzare un normale oggetto piuttosto di `Map`, poiché le chiavi sono stringhe.
Copy file name to clipboardExpand all lines: 1-js/05-data-types/07-map-set/article.md
+30-30Lines changed: 30 additions & 30 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,10 +3,10 @@
3
3
4
4
Finora abbiamo appreso le nozioni di base riguardo le seguenti strutture dati:
5
5
6
-
- Oggetti, per la memorizzazione di collezioni identificate da chiave.
6
+
- Oggetti, per la memorizzazione di collezioni identificate da una chiave.
7
7
- Array, per la memorizzazione di collezioni ordinate.
8
8
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`.
10
10
11
11
## Map
12
12
@@ -42,7 +42,7 @@ alert( map.size ); // 3
42
42
Come abbiamo potuto osservare, a differenza degli oggetti, le chiavi non vengono convertite a stringa. Sono quindi ammesse chiavi di qualunque tipo.
43
43
44
44
```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.
46
46
47
47
Quindi dovremmo utilizzare i metodi dedicati a `map`: `set`, `get` e gli altri.
48
48
```
@@ -54,7 +54,7 @@ Ad esempio:
54
54
```js run
55
55
let john = { name: "John" };
56
56
57
-
// per ogni utente, memorizziamo il contatore di visite
57
+
// per ogni utente, memorizziamo il contatore delle visite
58
58
let visitsCountMap = new Map();
59
59
60
60
// john è la chiave
@@ -63,7 +63,7 @@ visitsCountMap.set(john, 123);
63
63
alert( visitsCountMap.get(john) ); // 123
64
64
```
65
65
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.
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.
84
84
85
-
```smart header="How`Map` confronta le chiavi"
85
+
```smart header="Come`Map` confronta le chiavi"
86
86
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.
87
87
88
-
L'algoritmo di confronto non può essere ne cambiato ne modificato.
88
+
L'algoritmo di confronto non può essere né cambiato né modificato.
89
89
```
90
90
91
91
````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:
93
93
94
94
```js
95
95
map.set('1', 'str1')
@@ -103,8 +103,8 @@ map.set('1', 'str1')
103
103
Per iterare attraverso gli elementi di `Map`, esistono 3 metodi:
104
104
105
105
- `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`.
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:
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.
163
163
164
-
Quindi possiamo creare una `Map` da un oggetto come questo:
164
+
Quindi possiamo creare una `Map` da un oggetto, così:
165
165
166
166
```js run
167
167
let obj = {
@@ -192,14 +192,14 @@ let prices = Object.fromEntries([
192
192
['meat', 4]
193
193
]);
194
194
195
-
// now prices = { banana: 1, orange: 2, meat: 4 }
195
+
// ora prices = { banana: 1, orange: 2, meat: 4 }
196
196
197
197
alert(prices.orange); // 2
198
198
```
199
199
200
200
Possiamo utilizzare il metodo `Object.fromEntries` per ottenere un oggetto partendo da una `Map`.
201
201
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.
203
203
204
204
Quindi:
205
205
@@ -221,7 +221,7 @@ alert(obj.orange); // 2
221
221
222
222
Una chiamata a `map.entries()` ritorna un array di coppie chiave/valore, esattamente nel formato richiesto da `Object.fromEntries`.
223
223
224
-
Possiamo rendere la rica `(*)` ancora più corta:
224
+
Possiamo rendere la riga `(*)` ancora più corta:
225
225
```js
226
226
let obj = Object.fromEntries(map); // omettendo .entries()
227
227
```
@@ -235,15 +235,15 @@ Un `Set` è un tipo di collezione speciale - "set di valori" (senza chiavi), dov
235
235
I suoi metodi principali sono:
236
236
237
237
- `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.
239
239
- `set.delete(value)` -- rimuove il valore, ritorna `true` se `value` esiste, altrimenti `false`.
240
240
- `set.has(value)` -- ritorna `true` se il valore esiste nel set, altrimenti `false`.
241
241
- `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.
243
243
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.
245
245
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.
247
247
248
248
`Set` è esattamente la struttura dati che fa al caso nostro:
249
249
@@ -269,7 +269,7 @@ for (let user of set) {
269
269
}
270
270
```
271
271
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à.
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.
290
290
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.
292
292
293
-
Sono supportati anche i metodi di iterazione offerti da `Map`:
293
+
Sono supportati anche i metodi di iterazione di `Map`:
294
294
295
295
- `set.keys()` -- ritorna un oggetto per iterare sui valori,
296
296
- `set.values()` -- lo stesso di `set.keys()`, per compatibilità con `Map`,
297
297
- `set.entries()` -- ritorna un oggetto per iterare sulle voci `[value, value]`, esiste per compatibilità con `Map`.
298
298
299
299
## Riepilogo
300
300
301
-
`Map` -- è una collezione di valori identificati da chiave.
301
+
`Map` è una collezione di valori identificati da chiave.
302
302
303
303
Metodi e proprietà:
304
304
305
305
- `new Map([iterable])` -- crea la mappa, accetta un oggetto iterabile (opzionale, e.g. array) di coppie `[key,value]` per l'inizializzazione.
306
306
- `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`.
308
308
- `map.has(key)` -- ritorna `true` se la `key` esiste, `false` altrimenti.
309
309
- `map.delete(key)` -- rimuove il valore associato alla chiave.
310
310
- `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`.
312
312
313
313
Le differenze da un `Object` standard:
314
314
315
315
- Le chiavi possono essere di qualsiasi tipo, anche oggetti.
316
316
- Possiede metodi aggiuntivi, come la proprietà `size`.
317
317
318
-
`Set` -- è una collezione di valori unici.
318
+
`Set` è una collezione di valori unici.
319
319
320
320
Metodi e proprietà:
321
321
@@ -324,6 +324,6 @@ Metodi e proprietà:
324
324
- `set.delete(value)` -- rimuove il valore, ritorna `true` se `value` esiste, `false` altrimenti.
325
325
- `set.has(value)` -- ritorna `true` se il valore esiste nel set, `false` altrimenti.
326
326
- `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.
328
328
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.
// now readMessages has 1 element (technically memory may be cleaned later)
25
+
//ora readMessages ha un elemento (tecnicamente la memoria potrebbe essere ripulita dopo)
21
26
```
22
27
23
28
La struttura `WeakSet` consente di memorizzare un insieme di messaggi e di verificare molto rapidamente la presenza di un dato messaggio.
24
29
25
30
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.
26
31
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*.
28
35
29
36
Come qui:
30
37
```js
31
-
// the symbolic property is only known to our code
38
+
//la proprietà simbolica è visibile solo al nostro codice
32
39
let isRead =Symbol("isRead");
33
40
messages[0][isRead] =true;
34
41
```
35
42
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.
Copy file name to clipboardExpand all lines: 1-js/05-data-types/08-weakmap-weakset/02-recipients-when-read/task.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -16,4 +16,4 @@ let messages = [
16
16
17
17
Ora la domanda è: quale struttura di dati converrebbe utilizzare per memorizzare l'informazione: "quando è stato letto il messaggio?".
18
18
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