0

I asked a questions yesterday and received an awesome answer that solved most of my problem. I was trying to pair specific numeric values with 11 colors that were assigned at increments of 12 and shapes that where repeated every 12 increments.

ex: 0:black:circle, 1:black:cross, 2:black:star...12
    0:brown:circle, 1:brown:cross, 2:brown:star...12
    0:red:circle,   1:red:cross,   2:red:star...12

And so on until every number was assigned to a a color and shape. The code below does this. But it does it in a way that I didn't expect, the output is below.

struct ValueStruct {
var numValue: Int
var color: String
var shape: String

init(numValue: Int, color: String, shape: String) {
    self.numValue = numValue
    self.color = color
    self.shape = shape
  }
}

var startingNumValue = 0
let colorsArray = ["Black", "Brown", "Red", "Yellow", "Orange", "Green", "Grey", "Blue", "Purple", "Pink", "White"]
let shapesArray = ["Circle", "Cross", "Star", "Rectangle", "Triangle", "Square", "Heart", "Crown", "Line", "Diamond", "Ellipse", "Sun"]


var containingArray:[ValueStruct] = []

for colorItems in colorsArray {
for shapeItems in shapesArray {
    containingArray.append(ValueStruct(numValue: startingNumValue, color: colorItems, shape: shapeItems))
    startingNumValue += 1
}

This is what the output looks like in a playground so couple of issues with this.

1) Is this the most succinct method of doing this? The output of a normal loop is usually all in one window and it appears this is cycling in a way that stops than starts over & over until completion.

2) Is there a way to set an upper limit on the startingNumValue I only need it to go to 128 and I'm concerned about possible errors later on.

3) And finally this works fine in a playground but starting at the for colorItems in colorsArray line in a regular project it generates a Statements are not allowed at the top level error, any suggestions on the best way to handle that? enter image description here

Machavity
  • 30,841
  • 27
  • 92
  • 100

2 Answers2

2

I added an if statement to limit your array to 128 items. In a project, code other than your variable assignments need to be in a function. Try this:

import UIKit

struct ValueStruct {
    var numValue: Int
    var color: String
    var shape: String

    init(numValue: Int, color: String, shape: String) {
        self.numValue = numValue
        self.color = color
        self.shape = shape
    }
}

class ViewController: UIViewController, UITableViewDelegate {

    var startingNumValue = 0
    let colorsArray = ["Black", "Brown", "Red", "Yellow", "Orange", "Green", "Grey", "Blue", "Purple", "Pink", "White"]
    let shapesArray = ["Circle", "Cross", "Star", "Rectangle", "Triangle", "Square", "Heart", "Crown", "Line", "Diamond", "Ellipse", "Sun"]
    var containingArray:[ValueStruct] = []

    override func viewDidLoad() {
        super.viewDidLoad()

        for colorItems in colorsArray {
            for shapeItems in shapesArray {
                if startingNumValue < 128 {
                    containingArray.append(ValueStruct(numValue: startingNumValue, color: colorItems, shape: shapeItems))
                    startingNumValue += 1
                }
            }
        }
        println(startingNumValue)
    }
}
Steve Rosenberg
  • 19,348
  • 7
  • 46
  • 53
1

Another option would be to use a single for loop, and to select from the arrays using modulus arithmetic, as follows:

for i in 0..<128 {
    let colorIndex = i % (colorsArray.count)
    let shapesIndex = i / colorsArray.count
    containingArray.append(ValueStruct(numValue: i, color: colorsArray[colorIndex], shape: shapesArray[shapesIndex]))
}

But to case-harden this, you would need to watch that you do not go beyond the bounds of the shapesArray.

pbasdf
  • 21,386
  • 4
  • 43
  • 75