Shift
Shift

Reputation: 43

Swift: How to correctly compare String value to multiple values

I'm looking for the best method to compare a string value entered by the user and compare it to the proper Stage and Level value.

As of now I've made a lot of arrays like so

let Stage1Level1 = ["Phone","Computer,Television"]
let Stage1Level2 = ["Horse","Shoe"]
let Stage1Level3 = ["Milk"]

let Stage2Level1 = ["Snow","Sun"]
let Stage2Level2 = ["Smile","Cry","Water","Salt"]
let Stage2Level3 = ["Five"]

and so on...

So instead of making a long if statement checking for which Stage and Level the user entered I'm looking for the most efficient way of doing this.

Something like this:

var currentStage = 1
var currentLogo = 2

@IBAction func textFieldChanged(_ sender: Any) {

if textFieldChangedOut.text? == Stage(currentStage)Level(currentLogo){

print("Contains the value")

}
}

Upvotes: 0

Views: 1069

Answers (3)

E.Coms
E.Coms

Reputation: 11531

Maybe you can understand adding a dictionary to your current data.

    let Stage1Level1 = ["Phone","Computer,Television"]
    let Stage1Level2 = ["Horse","Shoe"]
    let Stage1Level3 = ["Milk"]

    let Stage2Level1 = ["Snow","Sun"]
    let Stage2Level2 = ["Smile","Cry","Water","Salt"]
    let Stage2Level3 = ["Five"]


    var currentStage = 1
    var currentLogo = 2

    var stageDict : [String: [String]] = [:]


    stageDict["Stage1Level1"] = Stage1Level1
    stageDict["Stage1Level2"] = Stage1Level2
    stageDict["Stage1Level3"] = Stage1Level3
    stageDict["Stage2Level1"] = Stage2Level1
    stageDict["Stage2Level2"] = Stage2Level2
    stageDict["Stage2Level3"] = Stage2Level3


  //You also can build by this way

   [[Stage1Level1, Stage1Level2, Stage1Level3], [Stage2Level1, Stage2Level2,Stage2Level3]]

   .enumerated().forEach{ stage in stage.element.enumerated().forEach{
    stageDict["Stage\(stage.offset+1)Level\($0.offset+1)"] = $0.element
    }
    }

    @IBAction func textFieldChanged(_ sender: Any) {

    if  stageDict["Stage\(currentStage)Level\(currentLogo)"]!.contains(textFieldChangedOut.text!) {
            print("Contains the value")

        }
    }

Upvotes: 1

Rob Napier
Rob Napier

Reputation: 299345

It's not really clear what these string are, but this is definitely the wrong data structure. I suspect you're looking for something like this, an array of stages that each contain an array of levels, which contain an array of strings.

struct Level {
    var values: [String]
}

struct Stage {
    var levels: [Level]
}

let stages = [
    Stage(levels: [
        Level(values: ["One", "Two"])
        Level(values: ["Horse", "Shoe"]),
        Level(values: ["One", "Two"]),
        ]),
    Stage(levels: [
        Level(values: ["Snow", "Sun"]),
        Level(values: ["Smile", "Cry"]),
        Level(values: ["Five", "Six"]),
        ]),
]

var currentStage = 1
var currentLogo = 2

// Remember that arrays are 0-indexed. If "currentStage" is 1-indexed
// you need to adjust it
let level = stages[currentStage - 1].levels[currentLogo - 1]
let words = level.values

if let text = textFieldChangedOut.text, words.contains(text) {
    print("Contains the value")
}

What you're trying to do with dynamically computing the name of the variable is impossible in pure Swift. There are ways to achieve it by bridging to ObjC, but they're not the right way to attack this problem.

Upvotes: 3

Joakim Danielson
Joakim Danielson

Reputation: 51971

I would create a struct of stage, level and the strings and have an array of that struct

struct StageLevel {
    let stage: Int
    let level: Int
    let words: [String]
}

let stageLevelArray: [StageLevel] = 
    [StageLevel(stage: 1, level: 1, words: ["Hello", "Hi"]), 
    StageLevel(stage: 1, level: 2, words: ["Red", "Blue", "Green"]), 
    StageLevel(stage: 2, level: 1, words: ["No", "Yes"])]

then you can filter out all elements for a chosen stage

let levels = stageLevelArray.filter( { $0.stage == 1} )

or filter out for a stage and a level

let selection = stageLevelArray.filter( { $0.stage == 1 && $0.level == 2 } )

or if you only want the levels or arrays

let levels = stageLevelArray.filter( { $0.stage == 1} ).map { $0.level}
let selection = stageLevelArray.filter( { $0.stage == 1 && $0.level == 2 } ).map { $0.words }

Upvotes: 1

Related Questions