zip ():
The zip
function allows us to merge 2 or more arrays into a Sequence
of a tuple. Zip
very useful we need to repeat two things at once, if not using zip
we will have to use For
loop and access each index from each array, while using zip
allows them to access elements from all arrays.
For example, if we have a user registration form and we want to update textFields to render a list of validation results received from the backend, usually we will do this:
1 2 3 4 5 6 7 8 9 |
func present(validationResults: [FieldValidationResult], inTextFields textFields: [MyTextField]) { for i in 0..<textFields.count { let field = textFields[i] let result = validationResults[i] field.render(validationResult: result) } } |
As for zip
1 2 3 4 5 6 7 |
func present(validationResults: [FieldValidationResult], inTextFields textFields: [MyTextField]) { for (field, result) in zip(textFields, validationResults) { field.render(validationResult: result) } } |
dump ():
The dump function is used to print objects. While to print objects, we use syntax like description
or debugDescription
, dump will print the contents of the object using reflection, giving the first result more sufficient including the levels of that object.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class Foo: NSObject { let bar: String = "bar" } let foo = Foo() print(foo) // <SwiftRocks.Foo: 0x1030b9250> dump(foo) // ▿ <SwiftRocks.Foo: 0x1030b9250> #0 // - super: NSObject // - bar: "bar" |
sequence ()
The sequence()
function lets us write recursive functions in a nicer syntax. Assuming we change the background color of a subvuew and all its parent views, we will probably use the while
loop like this:
1 2 3 4 5 6 |
var currentView: UIView? = self while currentView != nil { currentView?.backgroundColor = .green currentView = currentView?.superview } |
In this case, the most effective way to use is sequence()
, as the aspect of the method (currentView = currentView?.superview)
always the same, we can use sequence()
into a for loop like after:
1 2 3 4 |
for view in sequence(first: self, next: { $0.superview } ) { view.backgroundColor = .green } |
repeatElement()
For an object and the given number, the result is that a Sequence
can be repeated with the given number of times.
1 2 3 4 5 6 7 8 |
let repeated: Repeated<String> = repeatElement("SwiftRocks", count: 3) for value in repeated { print(value) } //SwiftRocks //SwiftRocks //SwiftRocks |
Most types of fish have special initialization as follows:
1 2 |
let array = [Int](repeating: 0, count: 10) |
So why do we use repeatElement
? The reason is because of performance. The return type of repeatElement()
is a Sequence Repeated<T>
, meaning it does nothing but provide iterative functionality. Assuming we want to replace a specific array of numbers with another one, one way to accomplish this is to use replaceSubrange
with another array:
1 2 3 4 |
array.replaceSubrange(2...7, with: [Int](repeating: 1, count: 6)) print(array) // [0, 0, 1, 1, 1, 1, 1, 1, 0, 0] |
Using [Int](repeating:)
with it to initialize an array of buffer
does nothing. If you only need an iterative function, then using repeatElement
will have better performance.
1 2 |
array.replaceSubrange(2...7, with: repeatElement(1, count: 6)) |
stride ():
stride()
is a function that is added to Swift as a way to create a for
loop to be able to ignore certain elements:
1 2 |
for (int i = 0; i < 10; i += 2) { ... } |
Now we can use stride
to achieve the purpose as the above code:
1 2 3 4 |
for i in stride(from: 0, to: 10, by: 2) { // from 0 to 9, skipping odd numbers. } |
Here’s how we can add the concept of “different dates” to the Date object so we can use stride()
: (in fact, Date()
has implemented the Strideable
method)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
extension Date: Strideable { func advanced(by n: Int) -> Date { return Calendar.current.date(byAdding: .day, value: n, to: self)! } func distance(to other: Date) -> Int { return Calendar.current.dateComponents([.day], from: other, to: self).day! } } let startDate = Date() let finalDate = startDate.advanced(by: 5) for date in stride(from: startDate, to: finalDate, by: 1) { print(date) } // March 24th // March 25th // March 26th // March 27th // March 28th |
Other global functions like:
max()
: Returns the maximum value of the argument.
min()
: Returns the minimum value of the argument.
abs()
: Returns the absolute value of the argument.
Reference: https://swiftrocks.com/useful-global-swift-functions