Como unir arrays em Swift? Análise completa com exemplos e segredos de desempenho
Se você já escreveu em Swift, certamente já se deparou com a tarefa: "Tenho dois arrays, como transformá-los em um?". A pergunta parece simples, mas esconde um mundo de otimizações e nuances. No Stack Overflow, essa pergunta acumulou milhares de visualizações — e não é à toa. Hoje, não vamos apenas mostrar como escrever código, mas vamos olhar por baixo do capô do compilador e descobrir o que realmente acontece quando você escreve array1 + array2. Vamos nessa!
A maneira mais óbvia: operador +
Vamos começar com o clássico. Em Swift, arrays podem ser somados como números:
let first = [1, 2, 3]let second = [4, 5, 6]let result = first + secondprint(result) // [1, 2, 3, 4, 5, 6]Bonito? Sim. Rápido? Nem sempre. Quando você usa +, o Swift cria um novo array e copia os elementos de ambos os arrays originais. Se seus arrays forem grandes (digamos, 100.000 elementos cada), isso é trabalho duplicado para o processador. Mas espere — há uma nuance chamada copy-on-write (COW).
A mágica do Copy-on-Write: como o Swift economiza memória
Swift é uma linguagem inteligente. Quando você simplesmente atribui um array a outro, ele não copia os dados imediatamente:
var a = [1, 2, 3]var b = a // Enquanto os dados não são modificados, a e b referenciam a mesma área de memóriab.append(4) // É aqui que ocorre a cópia real: b recebe sua própria cópiaIsso é chamado de copy-on-write. Mas ao unir com +, isso não funciona — o resultado é sempre um novo array. Por quê? Porque não estamos apenas referenciando dados antigos, mas criando uma nova coleção a partir de elementos de duas fontes diferentes. O compilador não pode garantir que os arrays originais não serão alterados, então ele faz uma cópia completa.
Método append(contentsOf:): quando a velocidade é mais importante
Se você precisa adicionar elementos de um array ao final de outro, sem criar um terceiro array, use append(contentsOf:):
var numbers = [1, 2, 3]let moreNumbers = [4, 5, 6]numbers.append(contentsOf: moreNumbers)print(numbers) // [1, 2, 3, 4, 5, 6]Neste caso, o Swift não cria um novo array — ele expande o array existente. Se o array numbers tiver memória reservada suficiente (capacity), os novos elementos são simplesmente copiados para o espaço livre. Caso contrário, ocorre uma realocação de memória, mas ainda assim é mais rápido do que criar um array do zero.
Dica de profissional: Se você sabe que vai adicionar muitos elementos, reserve memória antecipadamente com reserveCapacity():
var bigArray: [Int] = []bigArray.reserveCapacity(1000)for i in 0..<1000 { bigArray.append(i) // Nenhuma cópia desnecessária!}Método flatMap: união de arrays com transformação
Às vezes, não basta apenas unir arrays, mas também transformar cada elemento. É aí que entra o flatMap (ou compactMap para opcionais). A rigor, flatMap é destinado a "achatar" coleções, mas também pode ser usado para concatenação:
let arrays = [[1, 2], [3, 4], [5, 6]]let flattened = arrays.flatMap { $0 }print(flattened) // [1, 2, 3, 4, 5, 6]Por baixo dos panos, flatMap faz o mesmo que um loop com append(contentsOf:). Mas o código fica mais limpo e legível. No entanto, se você precisa apenas unir dois arrays — não use flatMap, é redundante.
reduce(into:) para união flexível
Se você tem um array de arrays e deseja uni-los com lógica adicional, experimente reduce(into:):
let arrayOfArrays = [[1, 2], [3, 4], [5, 6]]let merged = arrayOfArrays.reduce(into: [Int]()) { r