how to make a deep copy of a swift array of class objects
As a simple statement, you could use code like this:
var copiedArray = array.map{$0.copy()}
Note that the term "deepCopy" is a little misleading for what you're talking about. What if the array is heterogeneous and contains other containers like arrays, dictionaries, sets, and other custom container and "leaf" objects? What you should really do is to create a protocol DeepCopiable and make it a requirement that any object that conforms to DeepCopiable require that any child objects also conform to the DeepCopiable protocol, and write the deepCopy() method to recursively call deepCopy() on all child objects. That way you wind up with a deep copy that works at any arbitrary depth.
Thanks Duncan for your solution, here is an extension using it. Note that your class must adopt the NSCopying protocol. For how to do that see here https://www.hackingwithswift.com/example-code/system/how-to-copy-objects-in-swift-using-copy
extension Array {
func copiedElements() -> Array<Element> {
return self.map{
let copiable = $0 as! NSCopying
return copiable.copy() as! Element
}
}
}
If Element of an array is of reference type, conform that Element with NSCopying and implement copyWithZone
method.
class Book {
var name: String
init(_ name: String) {
self.name = name
}
}
extension Book: NSCopying {
func copy(with zone: NSZone? = nil) -> Any {
return Book(name)
}
}
Now implement an array extension to make a deep copy
extension Array where Element: NSCopying {
func copy() -> [Element] {
return self.map { $0.copy() as! Element }
}
}
Test the code base
let b1 = Book("Book1")
let b2 = Book("Book2")
let list = [b1, b2]
let clonedList = list.copy()
clonedList
is now copy of list
and won't affect each-other if you make change to any of two.