DEV Community

David Goyes
David Goyes

Posted on

Swift #19: Arreglos

Una colección es un contenedor de varios valores. Array es una colección genérica que puede contener una lista ordenada de valores.

Construir un arreglo

Después de definir el tipo de valores a almacenar, no se lo puede cambiar.

Algunos constructores:

  • Array<Type>()
  • Array(repeating: Value, count: Int): Crea count copias del mismo valor Value.
let list = Array(repeating: 0, count: 5)
print(list) // [0, 0, 0, 0, 0]
Enter fullscreen mode Exit fullscreen mode

Se puede usar el atajo [<Tipo de dato>]() para crear el arreglo (e.g. var nombre = [Int]()).

Swift también puede inferir el tipo de dato como arreglo, si se envuelven varios valores con corchetes y separados por coma (e.g. var nombreArreglo = [valor1, valor2, valor3]).

Acceso a una posición de un arreglo

Para acceder a un valor del arreglo (tanto para lectura como escritura), se especifica el índice entero entre corchetes. Para modificar un valor es obligatorio que el arreglo sea variable (var). Además, el índice a acceder debe ser menor que la longitud del arreglo; en caso contrario el programa fallará con una excepción.

var list = [5, 10, 15]
list[1] = 7
print(list[1]) // 7
Enter fullscreen mode Exit fullscreen mode

Concatenar arreglos

Se puede anexar un arreglo al final de otro con el operador +:

let list = [5, 10, 15]
let anotherList = [20, 25]
let result = list + anotherList
print(result) // [5, 10, 15, 20, 25]
Enter fullscreen mode Exit fullscreen mode

Arreglo de arreglos

Se puede crear un arreglo de arreglos. No es necesario que todos tengan la misma longitud. Para acceder a un elemento, hay buscar la fila con un primer índice, y luego el elemento dentro de esa fila con un segundo índice:

let firstRow = [1, 2, 3]
let secondRow = [2, 4, 6, 8]
let thirdRow = [3, 6]
let list: [[Int]] = [firstRow, secondRow, thirdRow]
let value = list[1][3]
print(value) // 8
Enter fullscreen mode Exit fullscreen mode

Limpiar un arreglo

Para limpiar el arreglo, basta con asignar la variable a un arreglo vacío.

var list = [5, 10, 15]
list = []
print(list) // []
Enter fullscreen mode Exit fullscreen mode

Iterar sobre un arreglo

Se puede iterar sobre el arreglo con un for in

var total = 0
var list = [1, 2, 3]
for value in list {
  total += value
}
print(total) // 6
Enter fullscreen mode Exit fullscreen mode

Arreglo como estructura

El tipo Array<T> ofrece algunos métodos y propiedades:

  • count
  • isEmpty
  • first: Retorna el primer elemento o nil si el arreglo está vacío.
  • firstIndex(of: Element): Busca desde el inicio del arreglo y retorna el índice del primer elemento que coincida con el argumento. Retorna nil si no encuentra nada.
  • firstIndex(where: Closure): Busca desde el inicio del arreglo y retorna el índice del primer elemento que cumpla el predicado.
  • first(where: Closure): Busca desde el inicio del arreglo y retorna el primer elemento que cumpla el predicado.
  • last: Retorna el último elemento o nil si el arreglo está vacío.
  • lastIndex(of: Element): Busca desde el final del arreglo y retorna el índice del último elemento que coincida con el argumento.
  • lastIndex(where: Closure): Busca desde el final del arreglo y retorna el índice del último elemento que cumpla el predicado.
  • last(where: Closure): Busca desde el final del arreglo y retorna el último elemento que cumpla el predicado.
  • append(Element)
  • insert(Element, at: Int): Añade un elemento al arreglo en una posición específica.
  • indices(where:): Retorna los índices de los elementos que cumplen con el predicado.
  • indices(of:): Retorna los índices de los elementos que son iguales al elemento pasado como argumento.
  • moveSubranges(_:to:): Mueve los elementos de los subrangos pasados por argumento, justo antes del elemento señalado por el índice especificado.

Al trabajar con índices, se usa un valor de tipo RangeSet que almacena un conjunto de valores de tipo Range con los índices de los elementos en el arreglo que cumplen con cierta condición.

let ages = [27, 28, 31, 57, 54]
let agesIndices = ages.indices(where: { $0 > 30 })
for age in ages[agesIndices] {
  print(age) // 31 57 54
}
ages.removeSubranges(agesIndices)
print(ages) // [27, 28]
Enter fullscreen mode Exit fullscreen mode

Cuando se usa RangeSet en lugar de un índice aislado para leer un arreglo, el sistema retorna una colección de tipo DiscontiguousSlice.

Para eliminar elementos usamos

  • remove(at:): Elimina un elemento específico
  • removeFirst(): Elimina el primer elemento y lo retorna.
  • removeLast(): Elimina el último elemento y lo retorna.
  • removeAll(where:): Elimina todos los elementos que cumplen con el predicado.
  • removeSubrange(Range): Elimina un rango de elementos del arreglo.
  • dropFirst(_ x: Int = 1): Elimina los primeros x elementos del arreglo.
  • dropLast(_ x: Int = 1): Elimina los últimos x elementos del arreglo.
  • removeSubrange(_:): Elimina los elementos especificados por los índices del argumento.
var list = [7, 66, -1, 5]
if !list.isEmpty {
  list.append(88) // [7, 66, -1, 5, 88]
  let removedValue = list.removeFirst() // [66, -1, 5, 88]
  print(removedValue) // 7
  list.insert(3, at: 2) // [66, -1, 3, 5, 88]
  list.insert(contentsOf: [1, 2], at: 2) // [66, -1, 1, 2, 3, 5, 88]
  list.removeAll(where: { $0 % 2 == 0 }) // [-1, 1, 3, 5]
  list.removeSubrange(1...2) // [-1, 5]
  list.replaceSubrange(0..<2, with: [3, 2]) // [3, 2]
  print(list) // [3, 2]
}
Enter fullscreen mode Exit fullscreen mode

Para organizar elementos usamos

  • sorted(): Retorna un arreglo con los elementos del arreglo original en orden ascendente.
  • sorted(by:): Retorna un arreglo con los elementos del arreglo original, con base en closure by.
  • shuffled(): Retorna un arreglo con los elementos del arreglo original en orden aleatorio.
  • reversed(): Invierte el orden de un arreglo y retorna un ReversedCollection.
  • swapAt(_ x: Int, _ y: Int): Intercambia los valores dados por los índices de los argumentos.
var list = [7, 32, 15]
list = list.shuffled() // e.g. [32, 7, 15]
let rev: ReversedCollection = list.reversed() // e.g. [15, 7, 32]

let nombres = ["Bruno", "Carlos", "Andrea"]
let nombresAscendente = nombres.sorted() // ["Andrea", "Bruno", "Carlos"]
let nombresDescendente = nombres.sorted(by: { $0 > $1 }) // ["Carlos", "Bruno", "Andrea"]
Enter fullscreen mode Exit fullscreen mode

Para extraer valores del arreglo usamos:

  • filter(_:): Retorna un arreglo con los elementos que pasan el filtro.
  • map(_:): Aplica una función de transformación a los elementos de un arreglo.
  • compactMap(_:): Aplica una función de transformación y filtra los valores que producen nil.
  • reduce(_ initialValue:,_ closure:)
  • contains(where:): Retorna true si al menos un elemento satisface la condición del closure.
  • allSatisfy(_ closure:): Retorna true si todos los elementos cumplen con el predicado.
  • difference(from: Array): Retorna CollectionDifference con todos los cambios necesarios para sincronizar los arreglos.
  • randomElement(): Selecciona un elemento de forma aleatoria. Retorna nil si está vacío.
  • replaceSubrange(Range, with: Array): Reemplaza un rango con los elementos del arreglo pasado por argumento.
  • joined(separator: String): Retorna un string con todos los valores del arreglo, conectados con separator.
var list = [7, 32, 15]
let found = list.contains(where: { $0 > 30 }) // true
if let randomNumber = list.randomElement() {
  print(randomNumber) // e.g. 15
}
let evenNumbers = list.filter({ $0 % 2 == 0 }) // [32]
let oddNumbers = list.filter({ $0 % 2 == 1 }) // [7, 15]
let increasedNumbers = list.map({ $0 + 2 }) // [9, 34, 17]
let stringNumbers = list.map(String.init) // ["7", "32", "15"]
let total = list.reduce(0, { $0 + $1 }) // 54
Enter fullscreen mode Exit fullscreen mode

Se puede pasar como función de transformación cualquier método que reciba el mismo número y tipo de parámetros. Por ejemplo, se puede pasar String.init a map para inicializar una nueva estructura con los valores recibidos en el closure.

Para obtener información del arreglo

  • count(where:): Cuenta los elementos que cumplen con una condición determinada.
  • enumerated(): Retorna un iterador con tuplas que contienen la pareja índice y elemento asociado.
  • min(): Retorna el valor más pequeño
  • max(): Retorna el valor más grande
var list = [7, 32, 15]
for (index, value) in list.enumerated() {
  print("\(index). Valor: \(value)")
}
// 0. Valor: 7
// 1. Valor: 32
// 2. Valor: 15
let ages = [10, 15, 20]
if let minAge = ages.min() {
  print("La persona más joven tiene \(minAge) años")
}
if let maxAge = ages.max() {
  print("La persona más vieja tiene \(maxAge) años")
}
Enter fullscreen mode Exit fullscreen mode

Antes de acceder a un índice de un arreglo, se debe validar que ese sea mayor que cero y menor que la longitud de éste.

var list = [7, 32, 15]
let index = 2
if index > 0 && index < list.count {
  print("Valor: \(list[index])")
}
// Valor: 15
Enter fullscreen mode Exit fullscreen mode

Pedazos de arreglos

Los arreglos creados a partir de un rango de índices son de tipo ArraySlice. Este es otro tipo de colección para almacenar datos provenientes de otro arreglo. Puede ser utilizado en un for in y puede ser convertido a arreglo con el constructor Array(ArraySlice).

let originalList = [7, 32, 15, -1]
let slice: ArraySlice = originalList[1...2] // [32, 15]
let newArray = Array(slice) // [32, 15]
Enter fullscreen mode Exit fullscreen mode

Top comments (0)