Using Stride in Swift 2.0

Using Stride in Swift 2.0

It changed a bit, here is the new syntax:

0.stride(to: 10, by: 2)

and

Array(0.stride(to: 10, by: 2)) // is [0, 2, 4, 6, 8]

if you take a look at here, you can see what types conform to the Strideable protocol.

As @RichFox pointed out, in Swift 3.0 the syntax changed back to the original global function form like:

stride(from:0, to: 10, by: 2)

Expression type '(_, _.Stride) - _' is ambiguous without more context

The expression .now() returns the type DispatchTime which is a struct.

let offsetTime = 0 initializes the variable as Int. The error is misleading, practically it's a type mismatch


Although the compiler can infer the type of an numeric literal

DispatchQueue.main.asyncAfter(deadline: .now() + 3)

the most reliable way to add an Int literal or variable to a DispatchTime value is a DispatchTimeInterval case with associated value.

DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(offsetTime)

and

DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(offsetTime) + .seconds(3))

There are four DispatchTimeInterval enumeration cases

  • .seconds(Int)
  • .milliseconds(Int)
  • .microseconds(Int)
  • .nanoseconds(Int)

How can I do a Swift for-in loop with a step?

The Swift synonym for a "step" is "stride" - the Strideable protocol in fact, implemented by many common numerical types.

The equivalent of (i = 1; i < max; i+=2) is:

for i in stride(from: 1, to: max, by: 2) {
// Do something
}

Alternatively, to get the equivalent of i<=max, use the through variant:

for i in stride(from: 1, through: max, by: 2) {
// Do something
}

Note that stride returns a StrideTo/StrideThrough, which conforms to Sequence, so anything you can do with a sequence, you can do with the result of a call to stride (ie map, forEach, filter, etc). For example:

stride(from: 1, to: max, by: 2).forEach { i in
// Do something
}

How to iterate for loop in reverse order in swift?

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 and stride(from: through: by:), which is used with inclusive ranges.

To iterate on a range in reverse order, they can be used as below:

for index in stride(from: 5, to: 1, by: -1) {
print(index)
}
//prints 5, 4, 3, 2

for index in stride(from: 5, through: 1, by: -1) {
print(index)
}
//prints 5, 4, 3, 2, 1

Note that neither of those is a Range member function. They are global functions that return either a StrideTo or a StrideThrough struct, which are defined differently from the Range struct.

A previous version of this answer used the by() member function of the Range struct, which was removed in beta 4. If you want to see how that worked, check the edit history.

Swift: what is the right way to split up a [String] resulting in a [[String]] with a given subarray size?

I wouldn't call it beautiful, but here's a method using map:

let numbers = ["1","2","3","4","5","6","7"]
let splitSize = 2
let chunks = numbers.startIndex.stride(to: numbers.count, by: splitSize).map {
numbers[$0 ..< $0.advancedBy(splitSize, limit: numbers.endIndex)]
}

The stride(to:by:) method gives you the indices for the first element of each chunk, so you can map those indices to a slice of the source array using advancedBy(distance:limit:).

A more "functional" approach would simply be to recurse over the array, like so:

func chunkArray<T>(s: [T], splitSize: Int) -> [[T]] {
if countElements(s) <= splitSize {
return [s]
} else {
return [Array<T>(s[0..<splitSize])] + chunkArray(Array<T>(s[splitSize..<s.count]), splitSize)
}
}

Loop - invoke 'stride' with CGFloat

import Foundation

let cf0 = CGFloat(0.0)
for cf in stride(from: cf0, through: 2.0, by: 1.0) {
print(cf, type(of: cf))
}

prints

0.0 CGFloat
1.0 CGFloat
2.0 CGFloat

Printing a star pattern in swift using stride function

If you want

1
12
123
1234

for i in 1..<5 { // or for i in stride(from: 1, to: 5, by: 1) {
for j in 1...i { // for j in stride(from: 1, through: i, by: 1) {
print(j, terminator: "")
}
print("")
}

If you want

*
**
***
****

for i in 1..<5 {
for _ in 1...i {
print("*", terminator: "")
}
print("")
}


Related Topics



Leave a reply



Submit