Int and Self.Index.Distance conflict in Swift 3 [duplicate] - swift

This question already has answers here:
Shuffle array swift 3
(4 answers)
Closed 6 years ago.
I have:
extension MutableCollection where Index == Int { // shuffle elements of self in place
mutating func shuffleInPlace() {
if count < 2 { return } // empty and single-element collections don't shuffle
for i in 0 ..< count - 1 {
let j = Int( arc4random_uniform( UInt32( count - i ) ) ) + i
guard i != j else { continue }
swap( &self[ i ], &self[ j ] )
...
...
and I'm getting the error:
Binary operator Binary operator '..<' cannot be applied to operands of type 'Int' and 'Self.IndexDistance'
Does anyone know how to rectify this?

Try this instead, wrap count -1 in parenthesis :
for i in 0 ..< (count - 1)

Related

How to write this for Loop in swift 4 [duplicate]

This question already has answers here:
How to iterate for loop in reverse order in swift?
(16 answers)
Reverse Range in Swift
(7 answers)
Closed 4 years ago.
for var i=count-2; i>=0; --i
{
if let nextControlPoint = firstControlPoints[i+1]
{
let controlPointX = (rhsArray[i].x.f - c[i] * nextControlPoint.x.f)/b[i]
let controlPointY = (rhsArray[i].y.f - c[i] * nextControlPoint.y.f)/b[i]
}
z += 1
}
You can write something like this
if count > 1 {
for i in (0...count-2).reversed() {
print(i)
}
}
The IF statement is needed because we cannot create a range where the first element is lower than the last one.

Why is result of filter with count not usable directly as conditional in Swift 3 [duplicate]

This question already has answers here:
How to use trailing closure in if condition?
(2 answers)
Using trailing closure in for-in loop
(3 answers)
Swift: Can not use array filter in if let statement condition
(1 answer)
Closed 5 years ago.
Noob here.
Why is this ok:
let lockedCount = myStructArray.filter{$0.isLocked == true}.count
and this not ok:
if myStructArray.filter{$0.isLocked == true}.count < 4 {
print("Fewer than 4 locked")
}
Swift has trouble parsing anonymous closure in the context of an if logical expression. You can work around this issue by parenthesizing the count expression:
if (myStructArray.filter{$0.isLocked == true}.count) < 4 {
// ^ ^
print("Fewer than 4 locked")
}
or
if (myStructArray.filter{$0.isLocked == true}.count < 4) {
// ^ ^
print("Fewer than 4 locked")
}
or
if myStructArray.filter({$0.isLocked == true}).count < 4 {
// ^ ^
print("Fewer than 4 locked")
}

Swift range operator for i = mymax; i >= 0 i-- [duplicate]

This question already has answers here:
#warning: C-style for statement is deprecated and will be removed in a future version of Swift [duplicate]
(4 answers)
Decrement index in a loop after Swift C-style loops deprecated
(5 answers)
Closed 6 years ago.
I facing problem in executing for loop in Swift 3. I can use loop for range operator ... and ..< but in may case, I want something like ..> but its not available.
How do I execute following loop in Swift 3?
var myMax = 20
for var i = myMax ; i >= 0 ; i -= 1 {
...
}
It's easy to reverse the loop. User reversed function.
Swift 3
let myMax = 20
for i in (1..<myMax).reversed() {
print(i)
}
You can also use stride as #ZaidPathan said :
This question have all answers with all versions : How to iterate for loop in reverse order in swift?
for i in (1..<20).reversed() {
print(i)
}
Hope it helps.Read More
Swift 3, You can use stride
var myMax = 20
for var i = myMax ; i > 0 ; i -= 1 {
}
//Equivalent
let myMax = 20
for value in stride(from: 20, to: 0, by: -1){
print(value)
}
var myMax = 20
for var i = myMax ; i >= 0 ; i -= 1 {
}
//Equivalent
for value in stride(from: 20, through: 0, by: -1){
print(value)
}

What's the Swift 3 equivalent of this C for loop? [duplicate]

This question already has answers here:
How to iterate for loop in reverse order in swift?
(16 answers)
Closed 6 years ago.
I am trying to do convert this C code:
int i;
for (i = 9; i >= 0; i--) {
}
in Swift 3, but I am not sure how to do it.
I know that if if I want to do it in ascending order if i, I can simply write:
for i in 0..<10 {
}
But how do I do it in descending order of i?
Thanks in advance!
Two ways:
// reverse a range
for i in (0...9).reversed() {
// ...
}
// use stride
for i in stride(from: 9, through: 0, by: -1) {
// ...
}
for i in (0 ..< 10).reversed() {
}

Refactor for-loop statement to swift 3.0

I have following line in my code:
for (i = 0, j = count - 1; i < count; j = i++)
Can anyone help to remove the two compiler warnings, that i++ will be removed in Swift 3.0 and C-style for statement is depreciated?
You could use this:
var j = count-1
for i in 0..<count {
defer { j = i } // This will keep the cycle "logic" all together, similarly to "j = i++"
// Cycle body
}
EDIT
As #t0rst noted, be careful using defer, since it will be executed no matter how its enclosing scope is exited, so it isn't a 100% replacement.
So while the standard for ( forInit ; forTest ; forNext ) { … } will not execute forNext in case of a break statement inside the cycle, a return or an exception, the defer will.
Read here for more
Alternatively, lets go crazy to avoid having to declare j as external to the loop scope!
Snippet 1
let count = 10
for (i, j) in [count-1..<count, 0..<count-1].flatten().enumerate() {
print(i, j)
}
/* 0 9
1 0
2 1
3 2
4 3
5 4
6 5
7 6
8 7
9 8 */
Snippet 2
for (i, j) in (-1..<count-1).map({ $0 < 0 ? count-1 : $0 }).enumerate() {
print(i, j)
}
Trying to win the prize for the craziest solution in this thread
Snippet 1
extension Int {
func j(count:Int) -> Int {
return (self + count - 1) % count
}
}
for i in 0..<count {
print(i, i.j(count))
}
Snippet 2
let count = 10
let iList = 0..<count
let jList = iList.map { ($0 + count - 1) % count }
zip(iList, jList).forEach { (i, j) in
print(i, j)
}
You could use a helper function to abstract away the wrapping of j as:
func go(count: Int, block: (Int, Int) -> ()) {
if count < 1 { return }
block(0, count - 1)
for i in 1 ..< count {
block(i, i - 1)
}
}