Dart: Collections
Collections são objetos que representam grupos de objetos.
No Dart existem 3 tipos de collections mais comuns:
- List: os objetos são identificado por índices
- Set: usado para armazenar apenas objetos únicos
- Map: os objetos são organizados no padrão chave e valor
List
Listas servem para agrupar outros objetos e seus item são identificados por índices
Listas sempre serão tipadas, seja de forma explícita ou implícita.
Exemplo de tipagem explícita:
List<String> ls = ['foo', 'bar', 'span'];
Exemplo de tipagem implícita:
var ls = [1, 2, 3] //Type: List<int>
No exemplo anterior, todos os items são do tipo int
, logo, nossa lista será
tipada como List<int>
. Ao tentar adicionar um novo item de um tipo diferente
teremos o seguinte erro.
ls.add('foo'); 👇
🚨 Error: The argument type ‘String’ can’t be assigned to the parameter type ‘int’.
Listas são iterables
, isso significa que seus items podem ser acessados sequencialmente.
var ls = [1, 2, 3];
print(ls is Iterable) //true
Iterando sobre uma lista.
var ls = ['foo', 'bar', 'span'];
for (var element in ls) {
print(element);
}// foo, bar, span
O objeto List
oferece vários métodos para manipulação de uma lista. Métodos para iteração, adição de novos item, remoção de item, busca de items, etc…
Exemplo: Somando todos os items de uma lista com o método .reduce()
.
var ls = [1, 2, 3, 4, 5];
ls.reduce((total, element) => total + element); // 15;
Exemplo: Filtrando todos os elementos maiores que 3 com o método .where()
.
var ls = [1, 2, 3, 4, 5];
ls.where((element) => element > 3); //[4, 5]
Exemplo: Concatenando todos os items com o método .join()
.
var ls = ['foo', 'bar', 'span'];
ls.join('-'); // foo-bar-span
Referência completa do objeto List
: https://api.dart.dev/stable/2.18.4/dart-core/List-class.html
Set
Set é uma coleção que aceita apenas elementos únicos
Item duplicados dentro de um set são excluídos.
Exemplo:
var st = {'foo', 'bar', 'span', 'foo'};
print(st); // foo, bar, span
As regras de tipagem explícita e implícita das listas também se aplicam aos sets.
var st = {'foo', 'bar', 'span', 'foo'};
print(st); // foo, bar, span
st.add(1);
🚨 Error: The argument type ‘int’ can’t be assigned to the parameter type ‘String’
Um List
pode ser convertido em um Set
de forma bem simples e vice versa, essa funcionalidade
é bem útil para remover itens duplicados de um List
.
Nesse exemplo usaremos os métodos .toSet()
e toList()
.
List<int> ls = [3, 1, 1, 4, 2, 2, 3, 1, 4, 5].toSet().toList();
print(ls); //[3, 1, 4, 2, 5]
Referência completa do objeto Set
: https://api.dart.dev/stable/2.18.4/dart-core/Set-class.html
Map
Map é uma coleção que identifica seus items por chave e valor
Exemplo:
var mp = {
'name': 'Peter',
'lastName': 'Parker',
'job': 'hero',
'City': 'Manhatan'
}; //Map<String, String>
Maps são generatics(Map<k, v>
) isso significa que podemos atribuir tipos específicos
pas as chaves e valores.
Map<int, Function> mp = {
1: () => 'first',
2: () => 'second',
3: () => 'third',
4: () => 'fourth'
};
Existem várias formas de iterar sobre um Map.
Map<String, String> mp = {
'name': 'Peter',
'lastName': 'Parker',
'job': 'hero',
'City': 'Manhatan'
}; //Map<String, String>
Usando o método .forEach
:
mp.forEach((key, value) {
print("$key -> $value");
});
Usando a propiedade .entries
:
for (var element in mp.entries) {
print('${element.key} -> ${element.value}');
}
Iterando somente sobre as chaves usando o .keys
:
mp.keys.forEach((keys) {
print(keys);
}); // name, lastName, job, city
Iterando somente sobre os values usando o .values
:
mp.values.forEach((value) {
print(value);
}); // Peter, Parker, hero, Manhatan
Referência completa do objeto Map
: https://api.dart.dev/stable/2.18.4/dart-core/Map-class.html
Operador spread
- spread operator (…): usado para adicionar os items de uma collection em outra collection.
- null-aware spread operator (…?): adiciona item de uma collection em outra collection, mas verifica se a collection é nula antes de adicionar os items.
Exemplos:
List<int> l1 = [1, 2, 3];
List<int> l2 = [4, 5, 6];
List<int> l3 = [...l1, ...l2]; // [1, 2, 3, 4, 5, 6]
var l1 = [1, 2, 3];
var l2 = null;
//verifica se l2 é nulo antes de adicionar os items
var l3 = [...l1, ...?l2]; // [1, 2, 3]
Operadores de controler
Também é possível usar operadores de controle(if
and for
) para manipular collections.
Exemplo: adicionar um item a uma lista se uma condição for verdadeira.
var a = 10;
var l1 = [1, 2, 3, if (a > 3) a]; // [1, 2, 3, 10]
Exemplo: comport listas utilizando o for
.
var l1 = [3, 4, 5];
var l2 = [1, 2, 3, for (var i in l1) i]; // [1, 2, 3, 3, 4, 5]