Recusiwe
Recusiwe

Reputation: 1140

Deep copy of array with elements containing an array?

I'm trying to make a deep copy of a list of the following objects:

struct Book {
    var title: String
    var author: String
    var pages: Int
}

struct BookShelf {
    var number: Int
}

class BookShelfViewModel {
    var bookShelf: BookShelf

    var number: Int
    var books: [BookViewModel]?

    init(bookShelf: BookShelf) {
        self.bookShelf = bookShelf

        self.number = bookShelf.number
    }

    required init(original: BookShelfViewModel) {
        self.bookShelf = original.bookShelf

        self.number = original.number
    }
}

class BookViewModel {
    var book: Book

    var title: String
    var author: String
    var pages: Int

    init(book: Book) {
        self.book = book

        self.title = book.title
        self.author = book.author
        self.pages = book.pages
    }

    required init(original: BookViewModel) {
        self.book = original.book

        self.title = original.title
        self.author = original.author
        self.pages = original.pages
    }
}

Books for BookShelf is fetched in the BookShelfViewModel.

If I go like:

var copiedArray = originalArray

for bs in copiedArray {
   bs.books = bs.books.filter { $0.title == "SampleTitle" }
}

The above filter both the copiedArray and the originalArray, and I obviously just want the copiedArray altered.

When I clone the array like this:

var originalArray = [BookShelfViewModel]()
... // Fill the array
var clonedArray = originalArray.clone()

clonedArray is cloned, but clonedArray.books is empty.

I've created the extension and followed this gist. How do I clone the array in the objects in the array?

I've done a quick playground to visualize the problem, hopefully it helps understand what I'm talking about.

enter image description here

Upvotes: 0

Views: 107

Answers (1)

Paulw11
Paulw11

Reputation: 114856

In your copying initialiser in BookShelfViewModel you don't actually clone the books array. You need to add self.books = original.books?.clone() to required init(original: BookShelfViewModel)

class BookShelfViewModel: Copying {
    var bookShelf: BookShelf

    var number: Int
    var books: [BookViewModel]?

    init(bookShelf: BookShelf) {
        self.bookShelf = bookShelf

        self.number = bookShelf.number
    }

    required init(original: BookShelfViewModel) {
        self.bookShelf = original.bookShelf
        self.books = original.books?.clone()
        self.number = original.number
    }
}

Upvotes: 1

Related Questions