Swift C-style loop [duplicate] - swift

This question already has answers here:
How can I do a Swift for-in loop with a step?
(1 answer)
Express for loops in swift with dynamic range
(2 answers)
Closed 6 years ago.
for (var i = 1; i < 1024; i *= 2) {
print(i)
}
How can this be done with for in loop?
The given solution is for += operator not *= operator. Please provide a solution for *= thanks.

In Swift 3 you can do
for f in sequence(first: 1, next: { $0 < (1024 / 2) ? $0 * 2 : nil }) {
print(f)
}
The concept of the sequence function is described in the documentation.
Printing an infinite list is easy, the code would just be
for f in sequence(first: 1, next: {$0 * 2}) {
print(f)
}
Since we want the program to stop at some point, we us the ternary operator ? to terminate the list once we reach the maximum value.
Since the last value we want to print is 512, the last value we have to double is 256. For 512 which does not satisfy the condition < (1024 / 2) we have nil and thereby stop.

Related

Swift way to C-style for loop that alters initial variable? [duplicate]

This question already has answers here:
is there anyway to increment exponentially in swift?
(4 answers)
Closed 2 years ago.
In many languages a for loop is able to alter i like the below. This for loop will double i each loop around.
for(int i = 0; i < total; i = i + i){}
Swift has for var i in stride(from: 0, to: total, by: N)
and for i in 0..<total
but neither allows us to alter i like the C style for loop above.
Is there a Swifty way to do this?
The goal is to change the pace each loop around instead of in a constant way like the N in stride.
You're looking for the sequence global function. The equivalent of your
for(int i = 0; i < total; i = i + i)
(I assume you meant 1, not 0, since otherwise you'd just get 0 forever, eh?) is:
let total = 100 // let's say
let seq = sequence(first:1) {$0 >= 100 ? nil : $0 + $0}
for i in seq {
print(i)
}
Output:
1
2
4
8
16
32
64
128

How can I traverse an array with stride? [duplicate]

This question already has an answer here:
How can I do a Swift for-in loop with a step?
(1 answer)
Closed 3 years ago.
I want to traverse an array with a stride. For example, I have an array [0,1,2,3,4,5,6,7,8,9].And I want to traverse this array with a stride of 3. The oc code likes below:
for (int i = 0; i < array.count; i += 3) {
}
How can I do that with swift.
You can use a for loop with stride to traverse the array
let testarray = [0,1,2,3,4,5,6,7,8,9]
for i in stride(from: 0, to: testarray.count, by: 3) {
print(testarray[i])
}

how to rewrite the following for loop in swift 3 syntax? [duplicate]

This question already has answers here:
Fix warning "C-style for Statement is deprecated" in Swift 3
(4 answers)
Decrement index in a loop after Swift C-style loops deprecated
(5 answers)
Closed 6 years ago.
for (int i = n-2; i >= 0; --i)
{
....
}
the automatic translation of the above to swift 3 syntax is this
for i in n-2 ... 0
{
}
this doesn't work, because n could be 1, in the c syntax, this is valid, the loop won't be triggered,
but in the swift 3 syntax, this will cause runtime error.
for i in stride(from: n-2, through: 0, by: -1) {
}
for i in (0 ... n-2).reversed() {
}

safely remove item while iterating backward in Swift 3

When I want to pass through and remove an item or items from an array (when certain conditions are met), I typically iterate backward in the C-style for-loop and remove the item by index, avoiding the problem of index numbers being changed of the next item to be processed, or the changing size of the list affecting how many times the loop is passed through. But the C for-loop has been removed in Swift 3.
Here is my Swift 2.3 code for the initialization of the loop:
for (var i = allowedItems.count - 1; i > -1; i -= 1)
Here is the monstrosity created by the Swift 3 converter:
for (i in ((-1 + 1)...allowedItems.count - 1).reversed())
This version does not compile however. ("Expected ',' separator" at the "in" operator).
I simplify the "-1 + 1" bit to zero:
for (i in (0...allowedItems.count - 1).reversed())
Now the error is "Expected Sequence expression for for-each loop".
What is the safe and hopefully reasonably elegant way of iterating backward in Swift 3, in which an index or counter variable is made available for use in specifying which item should be removed? This type of logic appears a number of places in my code so I want to make sure to find the best solution.
Thanks.
What is the safe and hopefully reasonably elegant way of iterating backward in Swift 3
The built-in way is:
for i in (0 ..< allowedItems.count).reversed()
The elegant way is:
for i in allowedItems.count >>> 0
(where >>> is the custom operator that I define here).
Use stride:
for i in stride(from: allowedItems.count - 1, through: 0, by: -1) {
}
What is the safe and hopefully reasonably elegant way of iterating
backward in Swift 3, in which an index or counter variable is made
available for use in specifying which item should be removed?
This doesn't answer the technical question, but possibly the underlying XY problem: have you considered simply filtering your array based on the criteria "when certain conditions are met"?
func certainConditionsForKeepingAreMet(_ element: YourElementType) -> Bool { /* ... */ }
allowedItems = allowedItems.filter(certainConditionsForKeepingAreMet)
E.g.
var allowedItems = [1, 3 ,6, 2]
func certainConditionsForKeepingAreMet(_ element: Int) -> Bool { return element < 3 }
allowedItems = allowedItems.filter(certainConditionsForKeepingAreMet)
print(allowedItems) // [1, 2]
If you'd like to remove and use the removed elements (on-the-fly), you could simply pipe the elements that are to be removed to some "use this element" function, in the course of checking the conditions for the elements.
func doSomethingWith(_ element: Int) { print("Removed", element) }
func certainConditionsForKeepingAreMet(_ element: Int) -> Bool {
if element >= 3 {
doSomethingWith(element)
return false
}
return true
}
var allowedItems = [1, 3 ,6, 2]
allowedItems = allowedItems.filter(certainConditionsForKeepingAreMet)
/* Removed 3
Removed 6 */
print(allowedItems) // [1, 2]

Struggling to understand the code - which tries to return the decimal digit 'n' places in from the right of the number

I'm new to Swift and is trying to learn the concept of extension. I saw this code in "the swift programming language", which tries to return the decimal digit 'n' places in from the right of the number. The code work fine, but I am struggling to understand how the code actually works.
Could someone explain it to me?
extension Int {
subscript(var digitIndex: Int) -> Int {
var decimalBase = 1
while digitIndex > 0 {
decimalBase *= 10
--digitIndex
}
return (self / decimalBase) % 10
}
}
746381295[0]
// returns 5
746381295[1]
// returns 9
746381295[2]
// returns 2
746381295[8]
// returns 7
746381295[9]
Extensions work by adding capability to existing types, with the caveat that they cannot introduce their own storage. In the case in point:
/*1*/ extension Int {
/*2*/ subscript(var digitIndex: Int) -> Int {
/*3*/ var decimalBase = 1
/*4*/ while digitIndex > 0 {
/*5*/ decimalBase *= 10
/*6*/ --digitIndex
/*7*/ }
/*8*/ return (self / decimalBase) % 10
}
}
Line 1 defines the extension as applying to all Int types.
Line 2 is setting up a new subscript operator for an Int, which will allow you to have 12345[4] and produce 'something'. Lines 3-8 define that something.
The while in lines 4-8 is multiplying decimalBase by 10 for 'digitIndex' times. A bit of a weird way of doing it, but never mind. The upshot is if digitIndex is 1, decimalBase is 10; if it's 2, decimal base is 100; 3 it's 1000; etc.
The guts is in line 8. First it retrieves self. Since the extension applies to an Int, self will be that integer value. It then divides it by decimalBase, and because they're both integers, any fractional part will be lost. Therefore in the case of 746381295[2] decimalBase will be 100 so you get 7463812. Then it uses '%' to get the remainder of the division by 10. So 7463812 divided by 10 is 746381 with a remainder of 2. So the returned value is 2.
Hope that explains it.
Pre-empting your question, I might use for in this case, instead of the while:
for _ in 0..<digitIndex {
decimalBase *= 10
}
I haven't thought too much about how often the above loops, it might run once to often or once too few, but you get the idea.
Even better would be to use the 'raising to the power' operator (not really sure what it's called).
decimalBase = 10 ^^ digitIndex
Then the whole definition could boil down to:
return (self / (10 ^^ digitIndex)) % 10
I will leave it to you to decide whether that's better or not.
Either way, I wouldn't really create this extension, and I assume it was just done for the purpose of demonstration.
Simply put, decimalBase is calculated to be 1 with an index of 0, 10 with an index of 1, 100 with an index of 2, 1,000 with an index of 3, and so on. In other words, decimalBase ends up equal to 10 ^ digitIndex.
So look at the case where digitIndex is 3, for instance. decimalBase will end up being 1,000, so:
746381259 / 1000 == 746381
and then:
746381 % 10 == 1
so that's how you get from 746381259[3] to 1.