Dart — Colecciones — Sets

2024-01-16T18:00:00-05:00 | 9 minutos de lectura | Actualizado en 2025-01-24T07:42:46-05:00

jaimetellezb
Dart — Colecciones — Sets

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!

Fuentes

© 2022 - 2025 jaimetellezb - Compartir guías y tutoriales de programación.

🌱 Powered by Hugo with theme Dream.

Sobre mí

alt

Ingeniero de software

Hola, bienvenidos a mi blog sobre guías y tutoriales de programación.

Aquí podrás encontrar guías y tutoriales sobre algunos temas de tecnología en general. La idea es poder ayudar a que ciertas cosas como configuraciones de nuevas herramientas sean más fáciles de abordar y utilizar. También pequeños proyectos donde se usen diferentes tecnologías como ejemplo.

Enlaces sociales