Jak zrobić dokładną kopię tablicy?
Mam trudności ze znalezieniem informacji o powielaniu tablicy w języku Swift.
Próbowałem użyć .copy()
var originalArray = [1, 2, 3, 4]
var duplicateArray = originalArray.copy()
Jak zrobić dokładną kopię tablicy?
Mam trudności ze znalezieniem informacji o powielaniu tablicy w języku Swift.
Próbowałem użyć .copy()
var originalArray = [1, 2, 3, 4]
var duplicateArray = originalArray.copy()
Odpowiedzi:
Tablice w Swift mają pełnowartościową semantykę, więc nie ma potrzeby robienia niczego wymyślnego.
var duplicateArray = originalArray
to wszystko czego potrzebujesz.
Jeśli zawartość twojej tablicy jest typem referencyjnym, to tak, spowoduje to tylko skopiowanie wskaźników do twoich obiektów. Aby wykonać głęboką kopię zawartości, należy zamiast tego użyć map
i wykonać kopię każdej instancji. W przypadku klas Foundation zgodnych z NSCopying
protokołem można skorzystać z copy()
metody:
let x = [NSMutableArray(), NSMutableArray(), NSMutableArray()]
let y = x
let z = x.map { $0.copy() }
x[0] === y[0] // true
x[0] === z[0] // false
Zauważ, że istnieją tu pułapki, przed którymi działa semantyka wartości języka Swift - na przykład, ponieważ NSArray
reprezentuje niezmienną tablicę, jej copy
metoda po prostu zwraca odwołanie do siebie, więc powyższy test przyniósłby nieoczekiwane wyniki.
var x = [UIView(), UIView(), UIView()] var y = x for i in x { NSLog("%p", i) } println("---") for i in y { NSLog("%p", i) }
i otrzymałem następujący wynik: 0x7fa82b0009e0 0x7fa82b012660 0x7fa82b012770 ---0x7fa82b0009e0 0x7fa82b012660 0x7fa82b012770
Nie wygląda na to, że jest kopiowany, czy wiesz, dlaczego?
x[0] == x[1]
ale x[0] === y[0]
powinna się nie udać
Nate ma rację. Jeśli pracujesz z tablicami pierwotnymi, wszystko, co musisz zrobić, to przypisać duplicateArray do oryginalnej tablicy.
Ze względu na kompletność, jeśli pracujesz z obiektem NSArray, wykonaj następujące czynności, aby wykonać pełną kopię NSArray:
var originalArray = [1, 2, 3, 4] as NSArray
var duplicateArray = NSArray(array:originalArray, copyItems: true)
Istnieje trzecia opcja odpowiedzi Nate'a:
let z = x.map { $0 } // different array with same objects
* EDYTOWANA * edycja zaczyna się tutaj
Powyższe jest zasadniczo takie samo jak poniżej i faktycznie użycie operatora równości poniżej będzie działać lepiej, ponieważ tablica nie zostanie skopiowana, chyba że zostanie zmieniona (jest to zgodne z projektem).
let z = x
Przeczytaj więcej tutaj: https://developer.apple.com/swift/blog/?id=10
* EDYTOWANE * edycja kończy się tutaj
dodanie lub usunięcie tej tablicy nie wpłynie na oryginalną tablicę. Jednak zmiana jakichkolwiek właściwości obiektów przechowywanych w tablicy byłaby widoczna w oryginalnej tablicy. Ponieważ obiekty w tablicy nie są kopiami (zakładając, że tablica zawiera obiekty, a nie liczby pierwotne).
var array1: [String] = ["john", "alan", "kristen"]; print(array1); var array2 = array1.map { $0 }; print(array2); array2[0] = "james"; print(array1); print(array2);
NSCopying
, zduplikuj tablicę:let z = x.map { $0.copy as! ClassX }
W przypadku zwykłych obiektów można zaimplementować protokół obsługujący kopiowanie i sprawić, by klasa obiektów implementowała ten protokół w następujący sposób:
protocol Copying {
init(original: Self)
}
extension Copying {
func copy() -> Self {
return Self.init(original: self)
}
}
A następnie rozszerzenie Array do klonowania:
extension Array where Element: Copying {
func clone() -> Array {
var copiedArray = Array<Element>()
for element in self {
copiedArray.append(element.copy())
}
return copiedArray
}
}
i to prawie wszystko, aby wyświetlić kod i próbkę, sprawdź tę istotę
object's
funkcji init
Jeśli chcesz skopiować elementy tablicy jakiegoś obiektu klasy. Następnie możesz postępować zgodnie z poniższym kodem bez używania protokołu NSCopying, ale musisz mieć metodę init, która powinna pobierać wszystkie parametry wymagane dla twojego obiektu. Oto kod przykładu do testowania na placu zabaw.
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