Dart



Dati: le mappe         

Come in altri linguaggi le mappe in Dart sono costituite da una sequenza (anche un solo elemento) di coppie chiave-valore. Evidentemente il valore è ottenuto tramite la sua chiave.
La definizione formale è semplice:

Map mappa = {chiave-1 : valore-1, chiave-2 : valore-2, ....., chiave-n : valore-n}

con i vari elementi separati dalla virgola e le coppie coordinate tramite i : (due punti). Ovviamente se non mettete nessun elemento, cosa perfettamente lecita, ma solo la coppia di parentesi graffe avrete una mappa vuota. Un primo esempio:

  Esempio 6.1
1
2
3
4
5
6
7
import 'dart:io' as io;
void main()
{
  map m01 = {1 : "uno", 2 : "due"};
  var x = m01[2];
  print(x);
}

La riga 4 introduce la nostra mappa mentre la riga 5 mostra in azione l'operatore [] all'interno del quale troviamo la chiave 2. Lo scopo, ovviamente, è di recuperare il valore associato a tale chiave. Infatti il programma stampa a video la stringa "due".
Come in molti altri linguaggi è. purtroppo, possibile avere due (o anche più) chiavi uguali ad indicare due (o più) valori corrispondenti diversi. In questo caso mi pare che in caso di ricerca con quella chiave, il risultato sia l'ultimo, anche se non ho fatto sufficienti test in merito. Questa cosa non mi piace ma è così. Pertanto potreste scrivere cose tipo:

map m01 = {1 : "uno", 2 : "due", 2 : "tre", 2 : "bbb"};

che risulteranno perfettamente legali.
La ricerca di una chiave non presente invece restituisce "null".

Le chiavi, come i valori, possono essere di natura diversa l'una dall'alltra per cui è ammissibile ad esempio una mappa siffatta

{ 1 : "uno", "due" : 2}

Le mappe hanno svariate proprietà e metodi vediamo di usarne alcune per capire come si lavora in maniera basica, sul sito ufficiale trovate ovviamente di tutto e di più:

Trovare il numero di elementi in una mappa: proprietà length

map m01 = {1 : "uno", 2 : "due", 3 : "tre", "c" : "bbb"};
print(m01.length);

il valore stampato sarà il numero 4, in quanto nella mappa vi sono appunto 4 elementi.

Verificare se la mappa possiede degli elementi o è vuota: proprietà isEmpty o isNotEmpty.

map m01 = {1 : "uno", 2 : "due", 3 : "tre", "c" : "bbb"};
print(m01.isEmpty);
print(m01.isNotEmpty);


Avremo un rusulato di tipo booleano, rispettivamente false e true.

Rimuovere tutti gli elementi da una mappa: metodo clear()

map m01 = {1 : "uno", 2 : "due", 3 : "tre", "c" : "bbb"};
m01.clear();
print(m01.length);


In questo caso il risultato sarà 0

Verificare se esiste una certa chiave: metodo containsKey(chiave)
il valore restituito sarà booleano, true o false a seconda che la chiave sia presente o no.

map m01 = {1 : "uno", 2 : "due", 3 : "tre", "c" : "bbb"};
print(m01.containsKey(2));


qui avremo "true" come output

Verificare se esiste un certo valore: metodo containsValue(valore)
anche qui il valore restituito è di tipo booleano, analogamente al caso precedente

map m01 = {1 : "uno", 2 : "due", 3 : "tre", "c" : "bbb"};
print(m01.containsValue("due"));


anche qui riceveremo come risposta "true"

Rimuovere uno specifico oggetto: metodo remove(chiave)

map m01 = {1 : "uno", 2 : "due", 3 : "tre", "c" : "bbb"};
m01.remove(1);
m01.remove(44);


A questo proposito si noti che la seconda e la terza riga lavorano in modo silente allo stesso modo con la differenza che la seconda elimina effettivamente un elemento, la terza non fa niente. Proprio niente. Questo di per sè è, a mio avviso, molto pericoloso in quanto potete credere di aver eliminato una coppia chiave valore e invece non è successo nulla, magari fosse solo per un banale errore di digitazione. Insomma dovrete ricorrere ad altre verifiche nel caso in cui la cancellazione di elementi fosse fondamentale per la vostra applicazione onde evitare problemi. Questa è cosa comune ad altri linguaggi.

Aggiungere un elemento ad una mappa: si ancora l'operatore []
mappa[chiave] = valore

map m01 = {1 : "uno", 2 : "due", 3 : "tre"};
m01[4] = "Quattro";
print(m01[4]);


In questo caso è stato aggiunto un elemento avente come valore la stringa "quattro" e come chiave il numero 4. Come è facile intuire questo è un modo per aggiungere elementi partendo da una mappa vuota.
Lo stesso operatore può essere usato per sostituire un valore corrispondente ad una certa chiave.

  Esempio 6.2
1
2
3
4
5
6
7
8
import 'dart:io' as io;
void main()
{
  map m01 = {1 : "uno", 2 : "due", 3 : "tre"};
  print(m01[3]);
  m01[3] = "quattro";
  print(m01[3]);
}

Come è facile vedere eseguendo questo piccolo programma prima viene stampata la stringa "tre" poi la stringa "quattro" in quanto in valore corrispondete alla chiave 3 è stato sostituito alla riga 6.

Per scorrere tutti i valori in una mappa vi propongo il seguente esempio, che dovrebbe essere abbastanza chiaro:

  Esempio 6.3
1
2
3
4
5
6
import 'dart:io' as io;
void main()
{
  map m01 = {1 : "uno", 2 : "due", 3 : "tre"};
  for(final k in m01.keys) print(m01[k]);
}

Oppure:

  Esempio 6.4
1
2
3
4
5
6
import 'dart:io' as io;
void main()
{
  map m01 = {1 : 1, 2 : 2};
  m01.forEach((k, x) => print("$k, $x"));
}


Per quanto riguarda la costruzione di una mappa, abbiamo visto il metodo più semplice ad inizio paragrafo. Un altro sistema è copiare una mappa da un'altra:

map m01 = {1 : 1, 2 : 2};
map m02 = new Map.from(m01);
for(final k in m02.keys) print(m02[k]);
m01[1] = 3;
for(final k in m02.keys) print(m02[k]);
for(final k in m01.keys) print(m01[k]);


L'esempio vi dimostrerà che la modifica sulla prima mappa non altera i valori della seconda.