My notes of Swift 5 language study
Built-In Collections
Collections of different kinds are supported by the standard library. Evermore does Swift put emphasis on sequences and collections resulting in very extensible model.
Arrays and Mutability
Most common collections in Swift - an ordered container of elements of the same type, providing random element access.
let FibonacciNumbers = [0, 1, 1, 2, 3, 5]
Modification of this array using append(_:)
will result in compile error. How come?!
Because let
defines constants, while var
variables.
Stick to constant by default, it's safer.
var mutableFibs = [0, 1, 1, 2, 3, 5]
mutableFibs.append(8)
mutableFibs.append(contentsOf: [13, 21])
// [0, 1, 1, 2, 3, 5, 8, 13, 21]
Evidently, let
variable containing reference to a class instance guarantees that the reference will never change, but he object the reference points to can chang, indeed.
Value semantics
An existing array assigned to a different variable copies it over.
var x = [1, 2, 3]
var y = x
y.append(4)
x is never modified, while a copy of it is made. Same thing happens with passing an array to a function - a local copy is made.
If to peep in NSArray
of Foundation, there are no mutating methods. NSMutableArray
is needed. But non-mutating NSArray
reference can be mutated "underneath"
let a = NSMutableArray(array: [1,2,3])
// I want a to be immutable
let b: NSArray = a
a.insert(4, at:3)
//fail :)
The correct way to write this therefore is to create a copy upon assignment
let c = NSMutableArray(array: [1,2,3])
//I want d to be immutable
let d = c.copy() as! NSArray
c.insert(4, at: 3)
Array Indexing
Swift arrays provide all the usual operations like isEmpty
, subscripting []
, and count
.
Fatal errors occur whenever out-of-bounds elements are requested.
Iteration over an array
for x in array
Iterate over all but the first element
for x in array.dropFirst()
Iterate over all but the last five elements
for x in array.dropLast(5)
Number all the elements
for (num, element) in array.enumerated()
Find location of a specific element
if let index = array.firstIndex {
return matchingLogic($0)
}
Transform all the elements
array.map {
return transformLogic($0)
}
Fetch only the creterion matching elements
array.filter {
match($0)
}
Note: subscripting operation that responds to an invalid index with a fatal error is arguably an "unsafe" operation. Swift discourages use of indecis. Mind, though, that subscripting in regard to memory safety always performs bound checks to prevent null pointer exception
Other operations like first
and last
return an optional value, which is nil
if the array is empty.
removeLast
method will halt if called on empty array, popLast
is safe.If array is used as a a stack checking for emptiness is encouraged so as not to fiddle with optional.
map
var squared: [Int] = []
for fib in FibonacciNumbers {
squared.append(fib * fib)
}
squared // [0, 1, 1, 4, 9, 25]
let squares = FibonacciNumbers.map {fib in fib * fib}
squares // [0, 1, 1, 4, 9, 25]
As a side note, map
method isn't hard to write, it's a generic for loop
Element
is the generic placeholder fpr whatever type the array contains, amd T is a new placeholder that represent the result of the elelement transformation. MyMap
function is oblivious to the types.
Ideally thought, signature must be func MyMap<T>(_ transform:(Element) throws -> T) rethrows -> [T]
, meaning that MyMap
will forward any error the transformation function might through to the caller.
Top comments (0)