Como eu faria uma duplicata exata de um array?
Estou tendo dificuldade em encontrar informações sobre a duplicação de uma matriz em Swift.
Tentei usar .copy()
var originalArray = [1, 2, 3, 4]
var duplicateArray = originalArray.copy()
Como eu faria uma duplicata exata de um array?
Estou tendo dificuldade em encontrar informações sobre a duplicação de uma matriz em Swift.
Tentei usar .copy()
var originalArray = [1, 2, 3, 4]
var duplicateArray = originalArray.copy()
Respostas:
Os arrays têm semântica de valor total em Swift, portanto, não há necessidade de nada sofisticado.
var duplicateArray = originalArray
é tudo o que você precisa.
Se o conteúdo do seu array for um tipo de referência, então sim, isso apenas copiará os ponteiros para seus objetos. Para realizar uma cópia profunda do conteúdo, você deve usar map
e realizar uma cópia de cada instância. Para classes Foundation que estão em conformidade com o NSCopying
protocolo, você pode usar o copy()
método:
let x = [NSMutableArray(), NSMutableArray(), NSMutableArray()]
let y = x
let z = x.map { $0.copy() }
x[0] === y[0] // true
x[0] === z[0] // false
Observe que há armadilhas aqui contra as quais a semântica de valor do Swift está trabalhando para protegê-lo - por exemplo, como NSArray
representa uma matriz imutável, seu copy
método apenas retorna uma referência para si mesmo, portanto, o teste acima produziria resultados inesperados.
var x = [UIView(), UIView(), UIView()] var y = x for i in x { NSLog("%p", i) } println("---") for i in y { NSLog("%p", i) }
e obtive esta saída: 0x7fa82b0009e0 0x7fa82b012660 0x7fa82b012770 ---0x7fa82b0009e0 0x7fa82b012660 0x7fa82b012770
Não parece que está sendo copiado, sabe por quê?
x[0] == x[1]
mas x[0] === y[0]
deve falhar
Nate está correto. Se estiver trabalhando com matrizes primitivas, tudo o que você precisa fazer é atribuir duplicateArray ao originalArray.
Para fins de integridade, se você estivesse trabalhando em um objeto NSArray, faria o seguinte para fazer uma cópia completa de um NSArray:
var originalArray = [1, 2, 3, 4] as NSArray
var duplicateArray = NSArray(array:originalArray, copyItems: true)
Há uma terceira opção para a resposta de Nate:
let z = x.map { $0 } // different array with same objects
* EDITADO * a edição começa aqui
Acima é essencialmente o mesmo que abaixo e, na verdade, o uso do operador de igualdade abaixo terá um desempenho melhor, pois a matriz não será copiada a menos que seja alterada (isso é por design).
let z = x
Leia mais aqui: https://developer.apple.com/swift/blog/?id=10
* EDITADO * a edição termina aqui
adicionar ou remover a esta matriz não afetará a matriz original. No entanto, a alteração de qualquer uma das propriedades dos objetos que a matriz contém seria vista na matriz original. Porque os objetos na matriz não são cópias (assumindo que a matriz contém objetos, não números primitivos).
var array1: [String] = ["john", "alan", "kristen"]; print(array1); var array2 = array1.map { $0 }; print(array2); array2[0] = "james"; print(array1); print(array2);
NSCopying
, duplique uma matriz:let z = x.map { $0.copy as! ClassX }
Para objetos normais, o que pode ser feito é implementar um protocolo que suporte cópia, e fazer com que a classe de objeto implemente este protocolo assim:
protocol Copying {
init(original: Self)
}
extension Copying {
func copy() -> Self {
return Self.init(original: self)
}
}
E então a extensão Array para clonagem:
extension Array where Element: Copying {
func clone() -> Array {
var copiedArray = Array<Element>()
for element in self {
copiedArray.append(element.copy())
}
return copiedArray
}
}
e isso é basicamente isso, para ver o código e uma amostra, verifique esta essência
object's
função init
Se você deseja copiar os itens de um array de algum objeto de classe. Então você pode seguir o código abaixo sem usar o protocolo NSCopying, mas você precisa ter um método init que deve levar todos os parâmetros que são necessários para o seu objeto. Aqui está o código de um exemplo para testar no playground.
class ABC {
var a = 0
func myCopy() -> ABC {
return ABC(value: self.a)
}
init(value: Int) {
self.a = value
}
}
var arrayA: [ABC] = [ABC(value: 1)]
var arrayB: [ABC] = arrayA.map { $0.myCopy() }
arrayB.first?.a = 2
print(arrayA.first?.a)//Prints 1
print(arrayB.first?.a)//Prints 2
var duplicateArray = originalArray