John Difool John Difool - 25 days ago 12
Swift Question

How to initialize an array using `repeating:count:` with distinct objects?

Surprisingly, the code below prints

SAME
while the initializer should call the
Z()
constructor each time. How can I initialize the array using this method with distinct instances of
Z
?

import Foundation

class Z {
var i: Int = 0
}

var z: [Z] = [Z](repeating: Z(), count: 10)

if z[0] === z[1] {
print("SAME")
} else {
print("NOT SAME")
}

Answer

I made an extension just for this!

extension Array {

    /// Creates a new empty Array with the specified capacity
    /// - Parameter capacity: the capacity to reserve, but not fill
    public init(capacity: Int) {
        self.init()
        self.reserveCapacity(capacity)
    }

    /// Create a new Array whose values are generated by the given closure.
    /// - Parameters:
    ///     - count:            The number of elements to generate
    ///     - elementGenerator: The closure that generates the elements.
    ///                         The index into which the element will be
    ///                         inserted is passed into the closure.
    public init(elementGenerator elementGenerator: (Int) -> Element, count: Int) {
        self.init(capacity: count)
        for i in 0 ..< count {
            self.append(elementGenerator(i))
        }
    }
}

class Z {
    var i: Int = 0
}

let z = Array(elementGenerator: { _ in Z() }, count: 10)

print(z)