unable to find enumerate() func in Swift standard library reference - ios

I'm new to Swift and is learning the concept of Array. I saw the code below from "swift programming language 2.1".
var array = [1,2,3,4,5]
for (index, value) in array.enumerate() {
print("\(value) at index \(index)")
}
I want to read a bit more about the enumerate() func so I looked up the Apple developer's page on Array, however, I could not find a func named enumerate() on this page. Am I looking at the wrong place or is there something I am missing? Coudl someone please give me a hand? Thanks in advance for any help!

When you encounter a Swift standard library function or method that you can't find documentation on, command-click on it in Xcode. That will take you to its definition, which in this case is
extension SequenceType {
/// Return a lazy `SequenceType` containing pairs (*n*, *x*), where
/// *n*s are consecutive `Int`s starting at zero, and *x*s are
/// the elements of `base`:
///
/// > for (n, c) in "Swift".characters.enumerate() {
/// print("\(n): '\(c)'")
/// }
/// 0: 'S'
/// 1: 'w'
/// 2: 'i'
/// 3: 'f'
/// 4: 't'
#warn_unused_result
public func enumerate() -> EnumerateSequence<Self>
}
What the above states is that enumerate() gives you back a tuple for each value in your collection, with the first element in the tuple being the index of the current item and the second being the value of that item.

Related

"Preloading" A Dictionary With Keys in Swift

This is a fairly simple issue, but one I would like to solve, as it MAY help with performance.
I want to find out if Swift has a way to create a Dictionary, specifying ONLY keys, and maybe no values, or a single value that is set in each entry.
In other words, I want to create a Dictionary object, and "preload" its keys. Since this is Swift, the values could be 0 or nil (or whatever is a default empty).
The reason for this, is so that I can avoid two loops, where I go through once, filling a Dictionary with keys and empty values, and a second one, where I then set those values (There's a practical reason for wanting this, which is a bit out of the scope of this question).
Here's sort of what I'm thinking:
func gimme_a_new_dictionary(_ inKeyArray:[Int]) -> [Int:Int] {
var ret:[Int:Int] = [:]
for key in inKeyArray {
ret[key] = 0
}
return ret
}
let test1 = gimme_a_new_dictionary([4,6,1,3,0,1000])
But I'm wondering if there's a quicker way to do the same thing (as in "language construct" way -I could probably figure out a faster way to do this in a function).
UPDATE: The first solution ALMOST works. It works fine in Mac/iOS. However, the Linux version of Swift 3 doesn't seem to have the uniqueKeysWithValues initializer, which is annoying.
func gimme_a_new_dictionary(_ inKeyArray:[Int]) -> [Int:Int] {
return Dictionary<Int,Int>(uniqueKeysWithValues: inKeyArray.map {($0, 0)})
}
let test1 = gimme_a_new_dictionary([4,6,1,3,0,1000])
For Swift 4, you can use the dictionary constructor that takes a sequence and use map to create the sequence of tuples from your array of keys:
let dict = Dictionary(uniqueKeysWithValues: [4,6,1,3,0,1000].map {($0, 0)})
I presume you could optimize your code in terms of allocation by specifying the minimum capacity during the initialization. However, one liner may be the above answer, it's essentially allocation and looping to add 0 in each position.
func gimme_a_new_dictionary(_ inKeyArray:[Int], minCapacity: Int) -> [Int:Int] {
var ret = Dictionray<Int, Int>(minimumCapacity: minCapacity)
for key in inKeyArray {
ret[key] = 0
}
return ret
}
let test1 = gimme_a_new_dictionary([4,6,1,3,0,1000])
Take a look at this official documentation:
/// Use this initializer to avoid intermediate reallocations when you know
/// how many key-value pairs you are adding to a dictionary. The actual
/// capacity of the created dictionary is the smallest power of 2 that
/// is greater than or equal to `minimumCapacity`.
///
/// - Parameter minimumCapacity: The minimum number of key-value pairs to
/// allocate buffer for in the new dictionary.
public init(minimumCapacity: Int)

Swift Collection underestimateCount usage

I wonder, what is the use case for Collection underestimateCount? Documentation says that it has the same complexity as standard Collection count.
/// Returns a value less than or equal to the number of elements in
/// `self`, *nondestructively*.
///
/// - Complexity: O(N).
public func underestimateCount() -> Int
But it doesn't describe when it should be used and for what reason.
underestimatedCount is actually a requirement of the Sequence protocol, and has a default implementation that just returns 0:
public var underestimatedCount: Int {
return 0
}
However, for sequences that provide their own implementation of underestimatedCount, this can be useful for logic that needs a lower bound of how long the sequence is, without having to iterate through it (remember that Sequence gives no guarantee of non-destructive iteration).
For example, the map(_:) method on Sequence (see its implementation here) uses underestimateCount in order to reserve an initial capacity for the resultant array:
public func map<T>(
_ transform: (Iterator.Element) throws -> T
) rethrows -> [T] {
let initialCapacity = underestimatedCount
var result = ContiguousArray<T>()
result.reserveCapacity(initialCapacity)
// ...
This allows map(_:) to minimise the cost of repeatedly appending to the result, as an initial block of memory has (possibly) already been allocated for it (although its worth noting in any case that ContiguousArray has an exponential growth strategy that amortises the cost of appending).
However, in the case of a Collection, the default implementation of underestimateCount actually just returns the collection's count:
public var underestimatedCount: Int {
// TODO: swift-3-indexing-model - review the following
return numericCast(count)
}
Which will be an O(1) operation for collections that conform to RandomAccessCollection, O(n) otherwise.
Therefore, because of this default implementation, using a Collection's underestimatedCount directly is definitely less common than using a Sequence's, as Collection guarantees non-destructive iteration, and in most cases underestimatedCount will just return the count.
Although, of course, custom collection types could provide their own implementation of underestimatedCount – giving a lower bound of how many elements they contain, in a possibly more efficient way than their count implementation, which could potentially be useful.
(Since the duplicate target I've suggested is somewhat outdated)
In Swift 3, the method underestimateCount() has been replaced by the computed property underestimatedCount. We can have a look at the source code for the implementation of the latter for Collection:
/// 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.
public var underestimatedCount: Int {
// TODO: swift-3-indexing-model - review the following
return numericCast(count)
}
/// 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.
public var count: IndexDistance {
return distance(from: startIndex, to: endIndex)
}
Its apparent that underestimatedCount simply makes use of count for types conforming to Collection (unless these types implements their own version of underestimatedCount).

How to remove an element of a given custom type value from an array in Swift

I want to remove element of custom type value from an array.
I want to pass a variant instance to function to remove it from array, I don't want to use removeAtIndex().
var favoriteVariants: [Variant]
func removeVariant(variant: Variant)
{
}
If Variant is Equatable and you only want to remove the first one that matches:
if let idx = favoriteVariants.indexOf(variant) {
favoriteVariants.removeAtIndex(idx)
}
If it isn’t Equatable and you have some other matching criteria to find just one to remove:
let idx = favoriteVariants.indexOf {
// match $0 to variant
}
if let idx = idx {
favoriteVariants.removeAtIndex(idx)
}
(these are assuming Swift 2.0 – if 1.2, it’s find(favoriteVariants, variant) instead of indexOf, and there isn’t a version that takes a closure, though it’s not too hard to write one)
If there are multiple ones you want to remove in one go:
favoriteVariants = favoriteVariants.filter {
// criteria to _keep_ any given favorite
}
All of these could be wrapped in extensions if what you want to do is general enough to justify it.

what does "->" mean in swift when declaring functions?

example function
func example(titles: [String]) `->` [UIButton] {
}
and where could i find more docs on this topic (docs relevant to functions declaring in swift)?
There is no > in swift function declarations - someone botched up the HTML rendering in the page you were reading. It was supposed to be -> (an arrow made up of a hypen and the greater than operator) that's used to denote the return type of the function.
The text was supposed to read
func example(titles: [String]) -> [UIButton] {
}
Which means the example function has one parameter called titles of type [String] (array of String) and it returns a [UIButton] (array of UIButton).
Assuming you're talking about -> the portion after that denotes the return value of the function.

Swift: syntax explanation - round brackets then "in"

I following tutorial and confused with following code:
let rectToDisplay = self.treasures.reduce(MKMapRectNull){
(mapRect: MKMapRect, treasure: Treasure) -> MKMapRect in
let treasurePointRect =
MKMapRect (origin: treasure.location.mapPoint, size: MKMapSize (width: 0, height: 0))
return MKMapRectUnion(mapRect, treasurePointRect)
}
In fact, I'm not understand only that line:
(mapRect: MKMapRect, treasure: Treasure) -> MKMapRect in
Is that some kind of function or something? What is the output? Im not quite understand meaning of that construction (struct: struct, someClass: someClass) -> Struct in
What is that logic? What is the meaning of "in"?
If you wondering, treasure is custom class that contain coordinate properties - latitude, longitude, etc.
I understand the "whole" meaning of that code snippet, but syntax of that line confuse me a bit..
Could you provide an explanation? Thanks a lot!
In Swift there are two ways to declare a function: with func, and with a closure expression:
// this is a function that takes an Int and returns a String
func f(i: Int) -> String { return i.description }
f(1) // returns "1"
// this is also a function that takes an Int and returns a String
let g = { (i: Int) -> String in return i.description }
g(1) // returns "1"
The latter is a closure expression – a quick way of defining a new function inline. They are most commonly used with functions that take functions (for example map, which takes an array and a function that transforms an element of that array, and runs the function on each element creating another array).
The syntax for closure expressions is they start, within braces, with arguments and return type, and then an in, and then the function body. Unlike with func, which starts with the func keyword, then the arguments and return type, followed by the function body within braces.
You don't always see the in because it can be left off. There are lots of shorthands that allow you to skip the arguments and return type (and the return keyword) altogether. But sometimes you need to give them, and then you need the in keyword.
You can read more about closure expressions in the Apple Swift book. You can read more about functions and closure basics here.

Resources