Reputation: 43
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
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
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
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