Swift 3: Replace C Style For-Loop with Float Increment

Swift 3: replace c style for-loop with float increment

you can use stride function stride(through:, by:) for this .. something like

for hue in (minHue).stride(through: maxHue, by: hueIncrement){
// ...
}

From Swift3.0, you can use stride(from:to:by:) or stride(from:through:by:) syntax

for hue in stride(from: minHue, through: maxHue, by: hueIncrement){
//....
}

warning: C-style for statement is deprecated and will be removed in a future version of Swift

Removing for init; comparison; increment {} and also remove ++ and -- easily. and use Swift's pretty for-in loop

   // WARNING: C-style for statement is deprecated and will be removed in a future version of Swift
for var i = 1; i <= 10; i += 1 {
print("I'm number \(i)")
}

Swift 2.2:

   // new swift style works well
for i in 1...10 {
print("I'm number \(i)")
}

For decrement index

  for index in 10.stride(to: 0, by: -1) {
print(index)
}

Or you can use reverse() like

  for index in (0 ..< 10).reverse() { ... }

for float type (there is no need to define any types to index)

 for index in 0.stride(to: 0.6, by: 0.1) {
print(index) //0.0 ,0.1, 0.2,0.3,0.4,0.5
}

Swift 3.0:

From Swift3.0, The stride(to:by:) method on Strideable has been replaced with a free function, stride(from:to:by:)

for i in stride(from: 0, to: 10, by: 1){
print(i)
}

For decrement index in Swift 3.0, you can use reversed()

for i in (0 ..< 5).reversed() {
print(i) // 4,3,2,1,0
}

enter image description here


Other then for each and stride(), you can use While Loops

var i = 0
while i < 10 {
i += 1
print(i)
}

Repeat-While Loop:

var a = 0
repeat {
a += 1
print(a)
} while a < 10

check out Control flows in The Swift Programming Language Guide

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
}

Type 'RangeCGFloat does not conform to protocol Sequence' (Swift 3)

Range<T>, unlike CountableRange<T> isn't a sequence, because it's unclear how to iterate it. Add 1 every time? 0.1? 0.001?

You can use stride instead:

for i in stride(from: 0 as CGFloat, to: needNumber, by: +1 as CGFloat) { //...

The ++ and -- operators have been deprecated Xcode 7.3

A full explanation here from Chris Lattner, Swift's creator. I'll summarize the points:

  1. It's another function you have to learn while learning Swift
  2. Not much shorter than x += 1
  3. Swift is not C. Shouldn't carry them over just to please C programmers
  4. Its main use is in C-style for loop: for i = 0; i < n; i++ { ... }, which Swift has better alternatives, like for i in 0..<n { ... } (C-style for loop is going out as well)
  5. Can be tricky to read and maintain, for eg, what's the value of x - ++x or foo(++x, x++)?
  6. Chris Lattner doesn't like it.

For those interested (and to avoid link rot), Lattner's reasons in his own words are:

  1. These operators increase the burden to learn Swift as a first programming language - or any other case where you don't already know these operators from a different language.

  2. Their expressive advantage is minimal - x++ is not much shorter than x += 1.

  3. Swift already deviates from C in that the =, += and other assignment-like operations returns Void (for a number of reasons). These operators are inconsistent with that model.

  4. Swift has powerful features that eliminate many of the common reasons you'd use ++i in a C-style for loop in other languages, so these are relatively infrequently used in well-written Swift code. These features include the for-in loop, ranges, enumerate, map, etc.

  5. Code that actually uses the result value of these operators is often confusing and subtle to a reader/maintainer of code. They encourage "overly tricky" code which may be cute, but difficult to understand.

  6. While Swift has well defined order of evaluation, any code that depended on it (like foo(++a, a++)) would be undesirable even if it was well-defined.

  7. These operators are applicable to relatively few types: integer and floating point scalars, and iterator-like concepts. They do not apply to complex numbers, matrices, etc.

Finally, these fail the metric of "if we didn't already have these, would we add them to Swift 3?"

How to check if a float is a multiple of another float in Swift

I believe that the modulo works only with integers, if I'm right you should do your own workaround to see if the given number is a multiple or not, which translate to: the result of the division must be an integer.
The code should be something like this:

let floatDivision = input/increment;
let isInteger = floor(floatDivision) == floatDivision // true
if (isInteger) {
println("Pass")
} else {
println("Fail")
}

And this should work with any increment number (even more than one decimal point digit).

EDIT

as James Said, the float division of 1.2 over 0.1 is not coded exactly as 12 but 11.9999... So I added the epsilon in the comparison:

let input = 1.2; 
let increment = 0.1;
let epsilon = 0.00000000000001;

let floatDivision = input/increment;
let dif = abs(round(floatDivision) - floatDivision);

println(String(format: "%.20f", floatDivision)); // 11.99999999999999822364
println(String(format: "%.20f", round(floatDivision))); // 12.00000000000000000000
println(String(format: "%.20f", dif)) // 0.00000000000000177636

let isInteger = dif < epsilon // Pass if (isInteger) {
println("Pass") } else {
println("Fail") }

Best of luck.

How to increment a NSNumber

Update: FYI, I personally like BoltClock's and DarkDusts's one-line answers better. They're more concise, and don't require additional variables.


In order to increment an NSNumber, you're going to have to get its value, increment that, and store it in a new NSNumber.

For instance, for an NSNumber holding an integer:

NSNumber *number = [NSNumber numberWithInt:...];
int value = [number intValue];
number = [NSNumber numberWithInt:value + 1];

Or for an NSNumber holding a floating-point number:

NSNumber *number = [NSNumber numberWithDouble:...];
double value = [number doubleValue];
number = [NSNumber numberWithDouble:value + 1.0];


Related Topics



Leave a reply



Submit