Array - Collections - Swift Programming

Array

Ordered collections of values

In Swift Array, Set, Dictionary types are implemented as generic collections


For arrays of most Element types, this storage is a contiguous block of memory.


If you create an array, a set, or a dictionary, and assign it to a variable, the collection that is created will be mutable.

  • This means that you can change (or mutate) the collection after it’s created by adding, removing, or changing items in the collection. 

If you assign an array, a set, or a dictionary to a constant, that collection is immutable, and its size and contents cannot be changed.


Arrays, like all variable-size collections in the standard library, use copy-on-write optimisation. Multiple copies of an array share the same storage until you modify one of the copies.

  • When that happens, the array being modified replaces its storage with a uniquely owned copy of itself, which is then modified in place. 
  • Optimisations are sometimes applied that can reduce the amount of copying.

If you assign an array, a set, or a dictionary to a constant, that collection is immutable, and its size and contents cannot be changed.


Every array reserves a specific amount of memory to hold its contents. When you add elements to an array and that array begins to exceed its reserved capacity, the array allocates a larger region of memory and copies its elements into the new storage. The new storage is a multiple of the old storage’s size. This exponential growth strategy means that appending an element happens in constant time, averaging the performance of many append operations. Append operations that trigger reallocation have a performance cost, but they occur less and less often as the array grows larger.

If you know approximately how many elements you will need to store, use the reserveCapacity(_:) method before appending to the array to avoid intermediate reallocations. Use the capacity and count properties to determine how many more elements the array can store without allocating larger storage.
 


Immutable Array


let sampleArray = ["a""b""c""a"]

print("Array: "sampleArray// Array:  ["a", "b", "c", "a"]


let arrayDefaultZeroCountThree = Array(repeating: 0.0, count: 3)

print(arrayDefaultZeroCountThree// [0.0, 0.0, 0.0]


let arrayDefaultOneCountTwo = Array(repeating: 1.0, count: 2)

print(arrayDefaultOneCountTwo// [1.0, 1.0]


let combinedArray = arrayDefaultZeroCountThree + arrayDefaultOneCountTwo

print(combinedArray// [0.0, 0.0, 0.0, 1.0, 1.0]


let combinedArrayOne = arrayDefaultOneCountTwo + arrayDefaultZeroCountThree

print(combinedArrayOne// [1.0, 1.0, 0.0, 0.0, 0.0]


// Accessing array elements with index values

let firstElement = sampleArray[0]

print(firstElement// "a"

//sampleArray[0] = "f" // you can't modify an array value set with "let"


// The number of elements in the array.

print("Immutable Array Count"sampleArray.count//Immutable array Count 4


// A value less than or equal to the number of elements in the collection. Complexity: O(1) if the collection conforms to RandomAccessCollection; otherwise, O(n), where n is the length of the collection.

print("Immutable Array Underestimated Count"sampleArray.underestimatedCount)

//Immutable array Underestimated Count 4


// The total number of elements that the array can contain without allocating new storage.

print("Immutable Array Capacity"sampleArray.capacity)

//Immutable array Capacity 4


Iterating over Array Elements


One

let arrayInt = [1,3,2,6,7,9,0]

print("for-in")

for value in arrayInt {

    print(value) // 1 to 0 from the array

}


Two

print("for-in with index")

for index in 0..<arrayInt.count {

    print("index: \(index) value: "arrayInt[index]) // 1 to 0 from the array

}


Three

print("for-in with enumeration having index & value")

for (index, value) in arrayInt.enumerated() {

    print("index: \(index) value: ", value) // 1 to 0 from the array

}


Four

//forEach is Array instance method that also iterates each element

///You cannot use a break or continue statement to exit the current call of the body closure or skip subsequent calls.

///Using the return statement in the body closure will exit only from the current call to body, not from any outer scope, and won’t skip subsequent calls.

print("forEach")

arrayInt.forEach { (value) in

     print(value)// 1 to 0 from the array

}


Five

print("for-in range 0 to max")

for value in arrayInt[0...] {

    print(value) // prints all elements

}


Six

print("for-in range 0 to specified index excluded")

for value in arrayInt[..<arrayInt.count] {

    print(value) // prints all elements

}


Seven

print("for-in range 0 to specified index included")

for value in arrayInt[...3] {

    print(value) // prints all elements after the position upto 3

}


Eight

print("for-in range specified index to max")

for value in arrayInt[3...] {

    print(value) // prints all elements after the position 3

}


Mutable Array


var sampleNames = ["a""b"]
print(sampleNames// ["a", "b"]

print("Mutable array Count"sampleNames.count
// Mutable array Count 2
print("Mutable array Underestimated Count"sampleNames.underestimatedCount)
// Mutable array underestimatedCount 2
print("Mutable array Capacity"sampleNames.capacity)
// Mutable array Capacity 2

sampleNames.append("c")
print("append"sampleNames// append ["a", "b", "c"]
//sampleNames.append(contentsOf: ["Shakia", "William"])

print("After Append one element")
print("Mutable array Count"sampleNames.count)
// Mutable array Count 3
print("Mutable array Underestimated Count"sampleNames.underestimatedCount)
// Mutable array underestimatedCount 3
print("Mutable array Capacity"sampleNames.capacity)
// Mutable array Capacity 4

sampleNames += ["d""e""f"]
print("+="sampleNames// += ["a", "b", "c", "d", "e", "f"]
print("After Append three elements")
print("Mutable array Count"sampleNames.count)
// Mutable array Count 6
print("Mutable array Underestimated Count"sampleNames.underestimatedCount
// Mutable array underestimatedCount 6
print("Mutable array Capacity"sampleNames.capacity
// Mutable array Capacity 8

sampleNames[0] = "Jockey"
print("zero index value updated - ",sampleNames
// zero index value updated -  ["Jockey", "b", "c", "d", "e", "f"]

sampleNames[1...5] = ["King""Queen""Ace"]
print("replaced range 1...5 with 3 values - "sampleNames
// replaced range 1...5 with 3 values -  ["Jockey", "King", "Queen", "Ace"]

sampleNames.insert("2", at: 0)
print("insert at 0"sampleNames)
// insert at 0 ["2", "Jockey", "King", "Queen", "Ace"]

sampleNames.remove(at: 0)
print("remove at 0"sampleNames)
// remove at 0 ["Jockey", "King", "Queen", "Ace"]

print("After Remove first element")
print("Mutable array Count"sampleNames.count)
// Mutable array Count 4
print("Mutable array Underestimated Count"sampleNames.underestimatedCount)
// Mutable array underestimatedCount 4
print("Mutable array Capacity"sampleNames.capacity)
// Mutable array Capacity 8

//sampleNames.removeFirst()
//sampleNames.removeLast()

sampleNames.removeFirst(2)
print("remove first 2"sampleNames)
// remove first 2 ["Queen", "Ace"]

sampleNames.removeLast(2)
print("remove last 2"sampleNames)
// remove last 2 []


Arrays Copying - Contain Value Types & Reference Type Values

Value Types

var arrayNames = ["a""b""c"]

var arrayNamesCopy = arrayNames

print("arrayNames: "arrayNames)

print("arrayNamesCopy: "arrayNamesCopy)


arrayNames[0] = "x"

print("After change - arrayNames: "arrayNames)

print("After change - arrayNames - arrayNamesCopy: "arrayNamesCopy)



Reference Types

class A {

    var a = "a"

}


let arrayA = [A(), A()]

let arrayACopy = arrayA


print("arrayA values")

for value in arrayA {

    print(value.a) // prints "a" twice

}

print("arrayACopy values")

for value in arrayACopy {

    print(value.a) // prints "a" twice

}


arrayA[0].a = "A"


print("arrayA values - After update")

for value in arrayA {

    print(value.a) // prints "A" & "a"

}


print("arrayACopy values - After update")

for value in arrayACopy {

    print(value.a// prints "A" & "a"

}



Comments