For-in loop goes one-too-far and finds 'nil' while unwrapping
Basically you've done something you're not supposed to do, and thus you've stumbled on something that's probably a compiler bug (because the compiler didn't stop you). Very nice!
Now the solution. You are evidently trying to unwrap with your Int!
. To unwrap safely, use for case
syntax:
let list:[Int?] = [1,2,3,4,5,6,7]
for case let x? in list
{
print(x) // 1, 2, 3, 4, 5, 6, 7
}
Another way (same result):
let list:[Int?] = [1,2,3,4,5,6,7]
list.flatMap{$0}.forEach{print($0)} // 1, 2, 3, 4, 5, 6, 7
Is it possible to implement a Swift SequenceType that contains nil elements?
Here is a (quite silly) example:
struct OddSequence : SequenceType {
func generate() -> GeneratorOf<Int?> {
var current = 0
return GeneratorOf<Int?>() {
if current >= 6 {
return nil
}
current++
if current % 2 == 0 {
return current
} else {
return Optional(nil)
}
}
}
}
for x in OddSequence() {
println(x)
}
Output:
nil
Optional(2)
nil
Optional(4)
nil
Optional(6)
The generator returns an optional (which can be Optional(nil)
) for each element,
and nil
if the sequence is exhausted.
See also "Optionals Case Study: valuesForKeys" in the Swift blog about the difference between nil
andOptional(nil)
and its applications.
Update for Swift 2:
struct OddSequence : SequenceType {
func generate() -> AnyGenerator<Int?> {
var current = 0
return anyGenerator {
if current >= 6 {
return nil
}
current++
if current % 2 == 0 {
return current
} else {
return Optional(nil)
}
}
}
}
for x in OddSequence() {
print(x)
}
How to make a function operate on a Sequence of Optional values?
Try this:
func firstValue<E, S: SequenceType where S.Generator.Element == Optional<E> >(seq: S) -> E? {
var g = seq.generate()
while let e:Optional<E> = g.next() {
if e != nil {
return e
}
}
return nil
}
let a:[Int?] = [nil,nil, 42, nil]
println(firstValue(a)) // -> 42 as Int?
I tested with Xcode Version 6.1.1 (6A2006) and Version 6.2 (6C86e)
Note
Without :Optional<E>
in while
condition, the compiler crashes.
And if we declare the function like this, the compiler clashes on some environment.
func firstValue<S: SequenceType, E where S.Generator.Element == Optional<E> > {
// ^^^^^^^^^^^^^^^^^^ replaced E and S
I think these are compiler bug. Please see the comments below.
EnumerateGenerator and Tuple
From "For-In Statement" in the Swift documentation:
A for-in statement allows a block of code to be executed once for each
item in a collection (or any type) that conforms to the SequenceType
protocol.The generate method is called on the collection expression to obtain a
value of a generator type—that is, a type that conforms to the
GeneratorType protocol. The program begins executing a loop by calling
the next method on the stream. If the value returned is not None, it
is assigned to the item pattern, the program executes the statements,
and then continues execution at the beginning of the loop. Otherwise,
the program does not perform assignment or execute the statements, and
it is finished executing the for-in statement.
So
for (index, value) in enumerate([1, 2, 3, 4, 5]) {
// ...
}
is identical to
let enumGenerator = enumerate([1, 2, 3, 4, 5])
var genFunc = enumGenerator.generate()
while let (index, value) = genFunc.next() {
// ...
}
let enumGenerator = enumerate([1, 2, 3, 4, 5])
returns aEnumerateGenerator<Seq.Generator>
(in this
case aEnumerateGenerator<IndexingGenerator<Array<Int>>>
). This conforms to theSequenceType
protocol.var genFunc = enumGenerator.generate()
returns again aEnumerateGenerator<Seq.Generator>
(probably a copy of theenumGenerator
).
This conforms to theGeneratorType
protocol.genFunc.next()
returnsElement?
whereElement
is a type alias for(index: Int, element: Base.Element)
.In this case,
next()
returns(index: Int, element: Int)?
. This next function
returns optional tuples until the array is exhausted, where it returnsnil
.
Avoid handling all exceptions until they've reached a global handler
Is it possible to ignore f's exceptions such that they ultimately become un-handled exceptions that can be handled globally?
In a word, no. The entire point of the design of Swift's error handling is that you must explicitly acknowledge the possibility of error at every stage.
It sounds to me like you're thinking of how Objective-C deals with NSException, but Swift isn't like that (and Error is not like NSException).
Enumerate/Iterate over an array using Blocks and know when it is completed
enumerateObjectsUsingBlock
executes synchronously. The enumeration is finished
when the method returns.
stop
is a reference to a Boolean which can be set to true
to stop further processing,
for example:
itemsArray.enumerateObjectsUsingBlock {
(object, index, stop) -> Void in
// process at most 5 elements:
if index == 4 {
stop.memory = true
}
}
Testing if stop == true
inside the block does not make sense.
Difference between Python xrange and generators?
Both range
and generator
objects are examples of iterable objects.
A range
is defined by a stopping value, with an optional starting value and optional step size allowed. The result is an iterable of integers. A range
also supports operations (like containment) that are not necessarily supported by other iterables.
A generator
is defined by a generator expression or a generator function, either of which results in an iterable of arbitrary values.
The iterable aspect of a range
object can be simulated by a generator
:
def myrange(stop, start=None, step=None):
if start is not None:
from_ = stop
to_ = start
else:
from_ = 0
to_ = stop
if step is None:
step = 1 if from_ < to_ else -1
while from_ < to_:
yield from_
from_ += step
Then
>>> list(myrange(1, 10))
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list(range(1, 10))
[1, 2, 3, 4, 5, 6, 7, 8, 9]
As Python 2 reached end-of-life nearly a year ago, there's not much reason to go into range
. Suffice it to say, in Python 2 range
was a function that returned a list of integers, while xrange
was a type whose value represents a list of integers. Python 3 did away with the function and reused the name for the type.
Related Topics
In Swift, How to Write a Generic Function to Resize an Array
Why Does Swiftui Uihostingcontroller Have Extra Spacing
Waiting for Alamofire in Unit Tests
If the Swift 'Guard' Statement Must Exit Scope, What Is the Definition of Scope
Session.Datataskwithurl Completionhandler Never Called
Detect Left and Right Click Events on Nsstatusitem (Swift)
Subtle Cast Warning When Using SQLite.Swift ... Binding? to Any
What's the Best Way to Iterate Over Results from an API, and Know When It's Finished
Why Is the Alert Triggering Out of Order If Value Is Not Updated
Adding Swift 3 Packages to Xcode 8 Using the Swift Package Manager
How to Disable User Interaction on Swiftui View