When I use the for loop in Playground, everything worked fine, until I changed the first parameter of for loop to be the highest value. (iterated in descending order)
Is this a bug? Did any one else have it?
for index in 510..509
{
var a = 10
}
The counter that displays the number of iterations that will be executions keeps ticking...
In Swift 4 and latter
You can use reversed() method for easily reverse values.
The reversed() method reverse the values.
Xcode 6 beta 4 added two functions to iterate on ranges with a step other than one:
stride(from: to: by:)
, which is used with exclusive ranges andstride(from: through: by:)
, which is used with inclusive ranges.To iterate on a range in reverse order, they can be used as below:
Note that neither of those is a
Range
member function. They are global functions that return either aStrideTo
or aStrideThrough
struct, which are defined differently from theRange
struct.A previous version of this answer used the
by()
member function of theRange
struct, which was removed in beta 4. If you want to see how that worked, check the edit history.With Swift 3, according to your needs, you may choose one of the eight following Playground code implementations in order to solve your problem.
#1. Using
CountableClosedRange
reversed()
methodCountableClosedRange
has a method calledreversed()
.reversed()
method has the following declaration:Usage:
#2. Using
CountableRange
reversed()
methodCountableRange
has a method calledreversed()
.reversed()
method has the following declaration:Usage:
#3. Using
sequence(first:next:)
functionSwift Standard Library provides a function called
sequence(first:next:)
.sequence(first:next:)
has the following declaration:Usage:
#4. Using
stride(from:through:by:)
functionSwift Standard Library provides a function called
stride(from:through:by:)
.stride(from:through:by:)
has the following declaration:Usage:
#5. Using
stride(from:to:by:)
functionSwift Standard Library provides a function called
stride(from:to:by:)
.stride(from:to:by:)
has the following declaration:Usage:
#6. Using
AnyIterator
init(_:)
initializerAnyIterator
has an initializer calledinit(_:)
.init(_:)
has the following declaration:Usage:
#7. Using
AnyIterator
init(_:)
initializerAnyIterator
has an initializer calledinit(_:)
.init(_:)
has the following declaration:Usage:
#8. Using a custom
Int
extension methodYou can refactor the previous code by creating an extension method for
Int
and wrapping your iterator in it:Updated for Swift 3
The answer below is a summary of the available options. Choose the one that best fits your needs.
reversed
: numbers in a rangeForward
Backward
reversed
: elements inSequenceType
Forward
Backward
reversed
: elements with an indexSometimes an index is needed when iterating through a collection. For that you can use
enumerate()
, which returns a tuple. The first element of the tuple is the index and the second element is the object.Forward
Backward
Note that as Ben Lachman noted in his answer, you probably want to do
.enumerated().reversed()
rather than.reversed().enumerated()
(which would make the index numbers increase).stride: numbers
Stride is way to iterate without using a range. There are two forms. The comments at the end of the code show what the range version would be (assuming the increment size is 1).
Forward
Backward
Changing the increment size to
-1
allows you to go backward.Note the
to
andthrough
difference.stride: elements of SequenceType
Forward by increments of 2
I'm using
2
in this example just to show another possibility.Backward
Notes
@matt has an interesting solution where he defines his own reverse operator and calls it
>>>
. It doesn't take much code to define and is used like this:Check out On C-Style For Loops Removed from Swift 3
Swift 4 onwards