En el Tutorial Swift de hoy aprenderemos acerca de los tres tipos de colecciones principales que ofrece Swift, conocidas como arrays, sets, y dictionaries, estas son utilizadas para almacenar arreglos de valores. Los Arrays son colecciones de valores ordenados. Los Sets son colecciones no ordenadas de valores únicos. Los Dictionaries son colecciones no ordenadas de asociaciones llave-valor.

En los arrays, sets y dictionaries en Swift, siempre se tiene claro los tipos de valores y las llaves que pueden almacenar. Esto significa que por error usted jamás podrá insertar un valor de un tipo de dato que no sea el de la colección. Estos nos brinda también seguridad sobre el tipo de valores que se van a recuperar de la misma.

Swift Colecciones

Mutabilidad de las colecciones

Si crea un array, un set o un dictionary, y lo asigna a una variable, la colección que se crea será mutable. Esto quiere decir que se puede cambiar (o mutar) la colección agregando, eliminando o cambiando elementos de la misma. Si asigna una array, un set o un dictionary a una constante, la colección será inmutable, y su tamaño y contenido no se podrán cambiar.

Se considera una buena práctica crear colecciones inmutables en todos los casos en los que la colección no vaya a ser modificada, ya que con esto le estamos permitiendo al compilador de Swift optimizar el rendimiento de estas colecciones.

Array

Al igual que en otros lenguajes de programación, en Swift también contamos con los Arreglos. En caso de que no se conozca de que estamos hablando, se podría decir que un array o arreglo es un conjunto de datos de un mismo tipo ordenados de forma lineal. Los componentes de un array se han de referenciar por medio del nombre del array y un índice de desplazamiento para indicar el componente deseado. A continuación veremos dos ejemplos de como declarar un Array y su inicialización, ambos ejemplos son equivalentes:

En ambos casos declaramos un Array de cadenas, someArray y otherArray representan constantes que nombran el arreglo para que luego pueda ser referenciado. A los elementos de un Array se puede acceder a través de subíndices especificando un valor de índice válido entre corchetes: someArray [0] aquí hacemos referencia al elemento en el índice 0, “Nery”.

Creación de un Array vacío

Podemos crear un arreglo vacío de un cierto tipo de dato utilizando la sintaxis de inicialización:

…la salida en pantalla sería:

Tengamos en cuenta que el tipo de la variable someInts se infiere a partir del tipo de dato con el que la inicializamos.

Otra opción hubiera sido:

Creando un Array con valores por defecto

Los Arrays en Swift también proporcionan un inicializador para la creación de una matriz de cierto tamaño, con todos sus valores establecidos a un mismo valor por defecto. A este inicializador se le pasa el número de elementos que se añade al nuevo arreglo (llamado count) y un valor por defecto del tipo de dato apropiado (llamado repeatedValue):

…la salida en pantalla:

Una alternativa pudiera ser:

…o esta otra versión donde Swift infiere el tipo de dato que conforma el Array:

También podemos crear un Array multidimensionales anidando pares de corchetes, en el que el nombre del tipo de dato de los elementos está contenido en el par más interior de corchetes. Por ejemplo, puede crear un Array tridimensional de números enteros utilizando tres conjuntos de corchetes:

Cuando se accede a los elementos en un Array multidimensional, en este caso de dos dimensiones, el índice más a la izquierda del subíndice se refiere al elemento en el índice “horizontal” del arreglo externo y lógicamente el de la derecha se refiere al elemento en el índice vertical. Esto significa que en el ejemplo anterior, array3D [0] se refiere a [[1, 2], [3, 4]], array3D [0] [1] se refiere a [3, 4], y array3D [0] [1 ] [1] se refiere al valor 4.

Accediendo y Modificando un Array

Veamos a continuación como añadir más elementos a nuestra lista de deseos:

…la salida en pantalla de este código sería:

En el anterior ejemplo hemos agrandado nuestro arreglo, hemos eliminado registros y hemos iterado sobre sus elementos incluso haciendo uso de rangos, todo esto utilizando varios métodos miembros de Array, pero estos no son todos, hay muchos más que los exhorto a descubrir.

Set

Un Set almacena valores distintos de un mismo tipo en una colección sin orden definido, es decir un Set de tipo String solamente almacenará cadenas de texto y donde no podrán repetirse los valores. Usualmente se hace uso de un Set en lugar de un Array cuando el orden de los elementos no sea importante, o cuando es necesario asegurarse de que un artículo sólo aparece una sola vez.

Creando e inicializando un Set vacío

Podemos crear un Set vacío de un cierto tipo de dato utilizando la sintaxis de inicialización:

…la salida en pantalla:

Creando un Set a partir de un Array literal

También se puede inicializar un Set con un Array literal, como una forma abreviada de escribir uno o más valores como una colección Set. El siguiente ejemplo crea un Set denominado generosFavoritos para almacenar valores de cadena:

En la variable generosFavoritos almacenamos los géneros musicales de nuestra preferencia, y se que estarán de acuerdo conmigo, en que no tiene sentido que quepa la posibilidad de que hayan valores repetidos, sencillamente esto no tendría sentido. Aquí hemos inicializado nuestro Set con tres valores de cadena (“Rock”, “Clásica” y “Hip hop”), estos escritos dentro de un Array literal.

La línea del ejemplo anterior también pudo haberse escrito de la siguiente forma:

…el tipo de dato String es inferido por Swift dado los valores con los que se ha iniclializado el Set en cuestión.

Accediendo y modificando un Set

Se puede acceder y modificar un conjunto a través de sus métodos y propiedades. Para averiguar el número de elementos de un Set, nos apoyamos en la propiedad count:

Podemos agregar un nuevo elemento a un Set haciendo una llamada al método insert(_:):

Ante la necesidad de eliminar un elemento de un Set lo podemos lograr mediante el método remove(_ :), el cual elimina el elemento si es un miembro del Set, devolviendo el valor eliminado, o nil en caso de que el mismo no estuviese contenido en el Set. Por otra parte, todos los elementos de un Set se pueden eliminar con el método removeAll ().

Uniones

Imaginemos que vamos de compras, a pos de algunas frutas para luego en casa preparar un coctel:

…pues nos falta comprar plátano, al mismo tiempo que advertimos la presencia de un amiga que se encuentra también haciendo las compras, luego de una corta charla acordamos terminar nuestras compras juntos y para ellos necesitamos ver todo cuanto tenemos en ambas cestas para programar mejor el recorrido en búsqueda de los que a ambos nos falta:

…la salida en pantalla sería:

En la línea 23 del anterior código hemos hecho uso del método union(_:) con la intención de unir los dos Set y conformar uno nuevo de nombre combineGroceryBag a partir de groceryBagfriendGroceryBag, conformando este nuevo por los elementos únicos en ambos Sets.

Sustracciones

Otro método de la colección Set que creo merece la pena hacer mencionar sería aquel que nos ayudaría ante la siguiente circunstancia: Continuemos con la historia anterior, asumamos que cuando llegamos a casa nuestro compañero de cuarto también se dirige hacia el mercado a hacer sus compras y también a comprar frutas ya que este también desea preparar un coctel de frutas. Dado el hecho de que somos compañeros de cuarto y que nosotros ya hemos comprado varias frutas pues compararemos los productos en común que tiene nuestra lista de compras y la de nuestro amigo, así este solamente tendría que comprar aquellos que no hemos traído.

…la salida en pantalla:

Para lograr esto último hemos hecho uso de el método substract el cual solamente nos retorna aquellos elementos que no son comunes entre el Set que ejecuta el método y aquel que es pasado como parámetro.

Al igual que Array, Set cuenta con muchos más métodos, muy útiles todos pero imposibles de nombrar aquí,  de hacerlo tornarían este tutorial excesivamente largo y aburrido.

Dictionary

Un diccionario almacena asociaciones entre llaves y valores del mismo tipo en una colección sin orden definido. Cada valor está asociado con una clave única, que actúa como un identificador para ese valor dentro del diccionario. A diferencia de los elementos de un Array, los elementos de un diccionario no tienen un orden específico. Hacemos uso de un diccionario cuando se necesita buscar valores en función de su identificador, casi de la misma manera que un diccionario en el mundo real cuando buscamos la definición de una palabra en particular.

El tipo de dato Dictionary es bastante útil y por ende bastante usado, su sintaxis es bien sencilla: Dictionary<Key, Value> donde cada campo se estructuraría en la forma [llave tipo: valor tipo], un ejemplo real luciría así:

…ambas línea son equivalentes.

A los valores de un diccionario se puede acceder a través de subíndices especificando la llave correspondiente entre corchetes: someDictionary [“Gise”] se refiere al valor asociado con la clave “Gise”. El subíndice devuelve un valor asociado a esta llave. Si la clave especificada no está contenida en el diccionario, el subíndice devuelve nil.

Creando e inicializando un Dictionary vacío

En ocaciones es necesario crear e inicializar un diccionario vacio:

…aquí un ejemplo de un diccionario de llave tipo Int y valores de tipo Double, inicializado con cero elementos. Pero también pudiéramos haberlo logrado de estas otras formas:

Accediendo y modificando un Dictionary

Tomando el siguiente diccionario como un ejemplo hipotético para el ejemplo, imaginemos que necesitamos iterar por cada elemento del mismo:

…la salida en pantalla:

En este ejemplo tenemos un bucle de tipo for-in, donde por cada elemento en el diccionario creamos una tupla cuyos tipos de datos son inferidos por el compilador dado el diccionario con el que estemos trabajando.

Modificar el valor de una llave y eliminar la tupla por completo es igual de sencillo:

…la salida de este código es la siguiente:

Creando un Array a partir de un Dictionary

Continuamos por mostrar como pudiéramos crear un arreglo a partir por ejemplo de los nombres de las llaves, veamos:

…la salida sería:

En este ejemplo tenemos un diccionario del cual extraemos los nombre de sus llaves mediante la propiedad computada de nombre keys, pasando estos datos al constructor de Array el cual retorna una estructura ya inicializada a nuestro arreglo myKeys por el cual luego iteramos sobre cada uno de sus elementos para poder visualizarlos en la salida en pantalla.

Comparativa

Antes de finalizar les dejaré una tabla con una pequeña comparativa entre las colecciones aquí comentadas:

Tipo de ColecciónOrdenadas?Única?Almacenamiento
ArrayNoElementos
DictionaryNoLlavesPares de Llave-Valor
SetNoElementos Elementos

Espero que todo cuanto se ha dicho aquí, de una forma u otra le haya servido de aprendizaje, de referencia, que haya valido su preciado tiempo.

Este artículo, al igual que el resto, será revisado con cierta frecuencia en pos de mantener un contenido de calidad y actualizado.

Cualquier sugerencia, ya sea errores a corregir, información o ejemplos a añadir será, más que bienvenida, necesaria!