Come farei un duplicato esatto di un array?
Ho difficoltà a trovare informazioni sulla duplicazione di un array in Swift.
Ho provato a usare .copy()
var originalArray = [1, 2, 3, 4]
var duplicateArray = originalArray.copy()
Come farei un duplicato esatto di un array?
Ho difficoltà a trovare informazioni sulla duplicazione di un array in Swift.
Ho provato a usare .copy()
var originalArray = [1, 2, 3, 4]
var duplicateArray = originalArray.copy()
Risposte:
Gli array hanno una semantica a pieno valore in Swift, quindi non c'è bisogno di niente di speciale.
var duplicateArray = originalArray
é tutto quello di cui hai bisogno.
Se il contenuto del tuo array è un tipo di riferimento, allora sì, questo copierà solo i puntatori ai tuoi oggetti. Per eseguire una copia completa dei contenuti, dovresti invece utilizzare map
ed eseguire una copia di ogni istanza. Per le classi Foundation conformi al NSCopying
protocollo, puoi utilizzare il copy()
metodo:
let x = [NSMutableArray(), NSMutableArray(), NSMutableArray()]
let y = x
let z = x.map { $0.copy() }
x[0] === y[0] // true
x[0] === z[0] // false
Nota che qui ci sono insidie da cui la semantica dei valori di Swift sta lavorando per proteggerti: ad esempio, poiché NSArray
rappresenta un array immutabile, il suo copy
metodo restituisce solo un riferimento a se stesso, quindi il test sopra produrrebbe risultati inaspettati.
var x = [UIView(), UIView(), UIView()] var y = x for i in x { NSLog("%p", i) } println("---") for i in y { NSLog("%p", i) }
e ho ottenuto questo output: 0x7fa82b0009e0 0x7fa82b012660 0x7fa82b012770 ---0x7fa82b0009e0 0x7fa82b012660 0x7fa82b012770
Non sembra che venga copiato, sai perché?
x[0] == x[1]
ma x[0] === y[0]
dovrebbe fallire
Nate ha ragione. Se stai lavorando con array primitivi, tutto ciò che devi fare è assegnare duplicateArray a originalArray.
Per ragioni di completezza, se stavi lavorando su un oggetto NSArray, dovresti fare quanto segue per fare una copia completa di un NSArray:
var originalArray = [1, 2, 3, 4] as NSArray
var duplicateArray = NSArray(array:originalArray, copyItems: true)
C'è una terza opzione per la risposta di Nate:
let z = x.map { $0 } // different array with same objects
* MODIFICATO * modifica inizia qui
Sopra è essenzialmente lo stesso come sotto e in realtà l'utilizzo dell'operatore di uguaglianza di seguito funzionerà meglio poiché l'array non verrà copiato a meno che non venga modificato (questo è di progettazione).
let z = x
Maggiori informazioni qui: https://developer.apple.com/swift/blog/?id=10
* MODIFICATO * modifica termina qui
l'aggiunta o la rimozione a questo array non influirà sull'array originale. Tuttavia, la modifica di qualsiasi proprietà degli oggetti contenuta nell'array verrebbe visualizzata nell'array originale. Perché gli oggetti nell'array non sono copie (supponendo che l'array contenga oggetti, non numeri primitivi).
var array1: [String] = ["john", "alan", "kristen"]; print(array1); var array2 = array1.map { $0 }; print(array2); array2[0] = "james"; print(array1); print(array2);
NSCopying
, duplica un array:let z = x.map { $0.copy as! ClassX }
Per oggetti normali ciò che si può fare è implementare un protocollo che supporti la copia e fare in modo che la classe dell'oggetto implementi questo protocollo in questo modo:
protocol Copying {
init(original: Self)
}
extension Copying {
func copy() -> Self {
return Self.init(original: self)
}
}
E poi l'estensione Array per la clonazione:
extension Array where Element: Copying {
func clone() -> Array {
var copiedArray = Array<Element>()
for element in self {
copiedArray.append(element.copy())
}
return copiedArray
}
}
e questo è più o meno tutto, per visualizzare il codice e un esempio, controllare questa sintesi
object's
funzione init
Se vuoi copiare gli elementi di un array di qualche oggetto di classe. Quindi puoi seguire il codice seguente senza utilizzare il protocollo NSCopying ma devi disporre di un metodo init che dovrebbe accettare tutti i parametri richiesti per il tuo oggetto. Ecco il codice per un esempio da testare su 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