Tabla de Contenido
Introducción
Los conjuntos (Set) se utilizan en varios lenguajes de programación, Dart no es la excepción en este caso y es el segundo tipo de colecciones que vemos después de las listas (List).
Conjuntos (Sets)
En Dart, un conjunto (Set) es una colección de elementos únicos y en desorden. Son similares a las listas pero los conjuntos no permiten elementos duplicados y tampoco tienen un orden específico como las listas.
// ejemplos de conjuntos
Set<int> numbers = {1, 2, 3, 4, 5};
Set<String> colors = {'Amarillo', 'Azul', 'Rojo'};
var sports = {'Fútbol', 'Ciclismo', 'Tenis'};
Constructores de un Conjunto (Set)
Constructor Set
Crea un conjunto (Set) vacío.
// Set(): constructor
var setConstructor = Set();
print(setConstructor); // {}
// agregamos un valor
setConstructor.add('value');
print(setConstructor); // {value}
Constructor Set.from
Crea un conjunto (Set) que contiene todos los elementos enviados como parámetro. Es importante que todos los elementos sean del mismo tipo que E.
// estructura del constructor
// elements: recibe un Iterable con los elementos
// que va a iniciar el conjunto.
// E: es el tipo de dato que queremos.
Set<E>.from(
Iterable elements
)
// ejemplo con clases
class Person {
final String name;
final String documentType;
final String documentNumber;
final int? age;
Person(
{required this.name,
required this.documentType,
required this.documentNumber,
this.age}) {}
}
void main() {
Set<Person> personSet = Set<Person>.from(
({Person(name: 'Pepe', documentType: 'CC', documentNumber: '34343434')}));
Set<Person> subSet = Set<Person>.from(personSet.where((e) => e is Person));
print(subSet); // {Instance of 'Person'}
print(personSet.first.name); // Pepe
}
// Ejemplo con literales
void main() {
final numbers = <num>{10, 20, 30};
final setFrom = Set<int>.from(numbers);
print(setFrom); // {10, 20, 30}
final colors = <String>{'blue', 'red'};
final setColors = Set<String>.from(colors);
print(setColors); // {blue, red}
}
Constructor Set.identity
Crea un conjunto de identidad vacío.
// estructura del constructor
Set<E>.identity()
// Ejemplo
void main() {
final Set<int> nums = Set<int>.identity();
nums.addAll({1, 2, 3});
print(nums); // {1, 2, 3}
}
Constructor Set.of
Crea un conjunto a partir de los elementos recibidos como parámetro.
// estructura del constructor
// elements: recibe un Iterable con los elementos
// que va a iniciar el conjunto.
// E: es el tipo de dato que queremos.
Set<E>.of(
Iterable<E> elements
)
// Ejemplo
void main() {
final baseSet = <String>{'A', 'B', 'C'};
final setOf = Set<String>.of(baseSet);
print(setOf); // {A, B, C}
}
Constructor Set.unmodifiable
Crea un conjunto de elementos que no se pueden modificar. El nuevo conjunto se comporta como un Set.of, solo que este no es modificable.
// estructura del constructor
// elements: recibe un Iterable con los elementos
// que va a iniciar el conjunto.
// E: es el tipo de dato que queremos.
Set<E>.unmodifiable(
Iterable<E> elements
)
// ejemplo
void main() {
final letters = <String>{'A', 'B', 'C'};
final unmodifiableSet = Set.unmodifiable(letters);
print(unmodifiableSet); // {A, B, C}
// Uncaught Error: Unsupported operation: Cannot change an unmodifiable set
unmodifiableSet.add('D');
}
Propiedades de un conjunto (Set)
Veremos a continuación, las propiedades que maneja Dart para las colecciones de conjuntos (Sets).
void main() {
// first -> E
// devuelve el primer elemento del conjunto (Set)
var letters = Set<String>.of({'A', 'B', 'C'});
print(letters.first); // A
// hashCode -> int
// es el código hash que identifica el objeto.
print(letters.hashCode);
// isEmpty → bool
// Valida si la colección no tiene elementos.
print(letters.isEmpty); // false
// isNotEmpty → bool
// valida si la colección tiene al menos un elemento.
print(letters.isNotEmpty); // true
print(letters.iterator.moveNext()); // true
// iterator → Iterator<E>
// Es una interfaz para obtener elementos, uno a la vez de un objeto.
print(letters.iterator); // Instance of '_LinkedHashSetIterator<String>'
var it = letters.iterator;
while (it.moveNext()) {
print(it.current);
// A
// B
// C
}
// last → E
// Obtiene el último elemento de la colección.
print(letters.last); // C
// length → int
// devuelve cantidad de elementos que tiene el conjunto.
print(letters.length); // 3
// runtimeType → Type
// Representa el tipo de dato en tiempo de ejecución.
print(letters.runtimeType); // _LinkedHashSet<String>
// single → E
// Valida que el conjunto solo tenga un elemento y
// devuelve ese elemento
var oneElement = {1};
print(oneElement.single); // 1
}
Métodos de un conjunto (Set)
Los conjuntos (Sets) tienen al igual que los Lists una serie de conjuntos que nos ayudan a trabajar mejor con ellos.
void main() {
var letters = Set<String>.from({'A', 'B', 'C'});
// add(E value) → bool
// Nos permite agregar un nuevo elemento al conjunto.
print(letters.add('D')); // true
print(letters); // {A, B, C, D}
// addAll(Iterable<E> elements) → void
// Agrega todos los elementos enviados al Set actual.
letters.addAll({'E', 'F'});
print(letters); // {A, B, C, D, E, F}
// any(bool test(E element)) → bool
// valida si algún elemento del conjunto cumple la condición.
bool anyVal = letters.any((element) => element.contains('E'));
print(anyVal); // true
// cast<R>() → Set<R>
// Proporciona una vista de este conjunto
// como un conjunto de instancias R.
Set<String> castSet = letters.cast<String>();
print(castSet); // {A, B, C, D, E, F}
// clear() → void
// elimina todos los elementos del conjunto.
letters.clear();
print(letters); // {}
// contains(Object? value) → bool
// Valida si el valor ingresado está en el conjunto.
final numbers = <int>{1, 2, 3, 4, 5};
print(numbers.contains(4)); // true
// containsAll(Iterable<Object?> other) → bool
// valida si el conjunto tiene todos los elementos del
// Iterable enviado.
print(numbers.contains(4)); // true
// difference(Set<Object?> other) → Set<E>
// Crea un nuevo conjunto con los elementos del actual
// que no están en el que envían por parámetro
print(numbers.difference({4, 5, 6})); // {1, 2, 3}
// elementAt(int index) → E
// retorna el elemento que coincide con el índice.
print(numbers.elementAt(2)); // 3
// every(bool test(E element)) → bool
// valida si cada elemento del conjunto cumple con la condición.
bool everyRes = numbers.every((element) => element > 3);
print(everyRes); // false
// expand<T>(Iterable<T> toElements(E element)) → Iterable<T>
// Expande cada elemento del iterable en cero o más elementos.
Iterable<int> count(int n) sync* {
for (var i = 1; i <= n; i++) {
yield i;
}
}
var numbers2 = [1, 3, 0, 2];
print(numbers2.expand(count)); // (1, 1, 2, 3, 1, 2)
// firstWhere(bool test(E element), {E orElse()?}) → E
// Obtiene el primer elemento que cumpla con la condición.
print(numbers.firstWhere((element) => element > 2)); // 3
// si ninguno cumple va al orElse
print(numbers.firstWhere((element) => element > 10, orElse: () => -1)); // -1
// fold<T>(T initialValue, T combine(T previousValue, E element)) → T
// Reduce una colección a un único valor combinando cada elemento
// y su valor existente.
print(numbers.fold<int>(
2, (previousValue, element) => previousValue + element)); // 17
// followedBy(Iterable<E> other) → Iterable<E>
// Crea la concatenación lazy entre este y otro iterable
print(numbers.followedBy(numbers2)); // (1, 2, 3, 4, 5, 1, 3, 0, 2)
// forEach(void action(E element)) → void
// itera todos los elementos del conjunto
numbers.forEach(print);
// 1
// 2
// 3
// 4
// 5
// intersection(Set<Object?> other) → Set<E>
// Crea un nuevo conjunto que es la intersección entre
// 2 conjuntos
print(numbers.intersection(<int>{4, 5})); // {4, 5}
// join([String separator = ""]) → String
// convierte cada elemento en una cadena y concatena todas.
// por el caracter que indiquemos
print(numbers.join('#')); // 1#2#3#4#5
// lastWhere(bool test(E element), {E orElse()?}) → E
// obtiene el último elemento que cumpla con la condición
print(numbers.lastWhere((item) => item < 4)); // 3
// lookup(Object? object) → E?
// si encuentra el objeto enviado lo devuelve.
print(numbers.lookup(3)); // 3
// map<T>(T toElement(E e)) → Iterable<T>
// devuelve un nuevo iterable lazy con los elementos
// que se crean llamando a toElement.
var values = numbers.map((product) => product as double);
var totalPrice = values.fold(0.0, (a, b) => a + b);
print(totalPrice); // 15
// noSuchMethod(Invocation invocation) → dynamic
// Invocado cuando se accede a un método o propiedad existente.
// reduce(E combine(E value, E element)) → E
// Reduce una colección a un solo valor combinado, usando la
// función proporcionada
final result = numbers.reduce((value, element) => value + element);
print(result); // 15
// remove(Object? value) → bool
// elimina el valor ingresado del conjunto.
print(numbers.remove(3)); // true
print(numbers); // {1, 2, 4, 5}
// removeAll(Iterable<Object?> elements) → void
// elimina todos los elementos ingresados de la lista.
numbers.removeAll({2, 4});
print(numbers); // {1, 5}
// removeWhere(bool test(E element)) → void
// elimina todos los elementos que cumplan la condición.
numbers.removeWhere((item) => item > 1);
print(numbers); // {1}
// retainAll(Iterable<Object?> elements) → void
// elimina todos los elementos de este conjunto
// que no están en el iterable enviado.
numbers.retainAll({2, 3});
print(numbers); // {}
// retainWhere(bool test(E element)) → void
// elimina todos los elementos que no cumplen la condición.
var numbers3 = Set<int>.of({1, 2, 3, 4, 5});
numbers3.retainWhere((item) => item > 2);
print(numbers3); // {3, 4, 5}
// singleWhere(bool test(E element), {E orElse()?}) → E
// Obtiene los elementos que cumplen la condición
print(numbers3.singleWhere((item) => item > 4)); // 5
// skip(int count) → Iterable<E>
// Crea un iterable que proporciona todos los elementos
// excepto el primero.
print(numbers3.skip(3)); // ()
// skipWhile(bool test(E value)) → Iterable<E>
// Crea un iterable que omite los elementos principales
// mientras se cumpla la condición.
print(numbers3.skipWhile((x) => x != 3)); // (3, 4, 5)
// take(int count) → Iterable<E>
// Crea un iterable lazy de los primeros elementos
// dado una cantidad count
print(numbers3.take(2)); // (3, 4)
// takeWhile(bool test(E value)) → Iterable<E>
// Crea un iterable lazy de los primeros elementos
// mientras cumpla condición
print(numbers3.takeWhile((item) => item > 2)); // (3, 4, 5)
// toList({bool growable = true}) → List<E>
// convierte el conjunto en la lista.
print(numbers3.toList()); // [3, 4, 5]
// toSet() → Set<E>
// crea un nuevo conjunto con los datos del actual.
print(numbers3.toSet()); // {3, 4, 5}
// toString() → String
// crea una representación de cadena de este conjunto.
print(numbers3.toString());
// union(Set<E> other) → Set<E>
// Crea un nuevo conjunto que contiene los elementos de este
// y otro conjunto enviado
print(numbers3.union(<int>{6, 7, 8})); // {3, 4, 5, 6, 7, 8}
// where(bool test(E element)) → Iterable<E>
// Crea un nuevo iterable lazy con todos los elementos
// que cumplen la condición
print(numbers3.where((item) => item > 3)); // (4, 5)
// whereType<T>() → Iterable<T>
print(numbers3.whereType()); // (3, 4, 5)
}
Conclusión
Vimos constructores, propiedades y métodos que usa Dart para los conjuntos (Sets), la mayoría son los mismos que se pueden usar en las listas.
¡Gracias por leer!
