swiftnewbie
swiftnewbie

Reputation: 211

nested for-loops on an array

I'm using SpriteKit and Swift 3 to create a simple game. I have an array of Rings/Circles:

mRings = [mRingOne, mRingTwo, mRingThree, mRingFour, mRingFive]

each object in the array has a different color, In some point in the game I want to change the color of each ring, but I have 2 condition for this to happen: 1. a ring should not have the color it had one iteration before. 2. each ring should be in a different color from the others.

for the first condition I did this:

func changeRingsColor(){
    var previousColor: UIColor?
    for ring in mRings {
        previousColor = ring.fillColor
        repeat{
            ring.fillColor = hexStringToUIColor(hex: mColors[Int(arc4random_uniform(UInt32(5)))])
        }while(ring.fillColor.isEqual(previousColor))
    }
}

and it is working, however, I couldn't figure out a way to answer the second condition. In Java I would probably do something like this:

    for (int i=0; i<mRings.length; i++){
      for( int j=1; j<mRings.length; j++){
        if (ring[i].fillColor == ring[j].fillColor){
            generate another color for 'j' ring.
        }
    }
 }

but nothing I tried worked. Hope you guys can help me, Thanks in advance!

btw, mColors is an array of 5 different colors, from there I pick the colors.

Upvotes: 0

Views: 1789

Answers (3)

Sulthan
Sulthan

Reputation: 130092

Something like this will work:

func changeRingsColor(){
    // extract the previous colors
    let colors = rings.map { $0.fillColor }
    // the order in which the rings will pass color to each other
    let passOrder = mRings.indices.shuffled()

    for i in mRings.indices {
        let previous = i == 0 ? mRings.count - 1 : i - 1        
        mRings[passOrder[i]].fillColor = colors[passOrder[previous]]
    }
}

Using this implementation of shuffled

How does it work?

Instead of randomly choosing a color for each individual ring, I am randomly generating an order in which the rings will swap the colors (passOrder). Since every ring will pass its color to a different ring in that order, you can be sure no color will stay the same.

Upvotes: 0

Connor Neville
Connor Neville

Reputation: 7351

I'm going to ignore some of the implementation details and focus on the core of the question, which is:

  • Loop through an array
  • Within each loop, start a new loop at the current index to the end of the array.

Let me know if I'm misunderstanding the above. But I would do it like this:

for (index, ring) in mRings.enumerated() {
    let remainingRings = mRings[index+1..<mRings.count]
    for otherRing in remainingRings {
        print("Now comparing \(ring) to \(otherRing)")
    }
}

First, enumerated() gives you both the current ring, and the index, on each iteration of the first for loop. Then, we slice the array from the current index to the end (remainingRings), and loop through those.

Upvotes: 1

Oleg Gordiichuk
Oleg Gordiichuk

Reputation: 15512

It is possible to rewrite Java code in this way :

let mRings = ["mRingOne", "mRingTwo", "mRingThree", "mRingFour", "mRingFive"]

for (index, item) in mRings.enumerated() {
    for item in index + 1..<mRings.count {

    }
}

Upvotes: 0

Related Questions