Reputation: 15
I am new at iOS development. I am trying to do the following: Store a title, that allows any number of subcategories to be added below it. Each subcategory needs to have 2 integers attached to it. I need to be able to use, edit, remove, and add new titles, subcategories, and integers.
"Title":
"Subcategory": int, int
"Subcategory": int, int
"Title":
"Subcategory": int, int
"Subcategory": int, int
"Subcategory": int, int
"Subcategory": int, int
I have tried several times with structs and arrays. For example:
struct everyThing {
var titles = ["Title 1", "Title 2", "Title 3"]
var subcategories = ["subcat1", "subcat2", "subcat3", "subcat4", "subcat5"]
var integers: [Double] = [5.0,10.0,7.0,15,3,6,7,8,12,14,13,15]
}
struct grouping1{
var title = everyThing().titles[0]
var subcategories = everyThing().subcategories[0..<2]
var integers = everyThing().workRest[0..<2]
}
struct grouping2{
var title = everyThing().titles[1]
var subcategories = everyThing().integers[2..<4]
var integers = everyThing().integers[2..<4]
}
It becomes impossible to keep track of and scale, as any number of subcategories can be added under a particular title.
Any ideas of the best way to organize this data? Let me know if this is too vague.
Upvotes: 0
Views: 458
Reputation: 59496
You need 2 model values
struct SubCategory {
let title: String
let value0: Int
let value1: Int
}
struct Category {
var title: String
private (set) var subcategories = [SubCategory]()
init(title:String) {
self.title = title
}
}
Let's see what you can do now.
var categories = [Category]()
let category0 = Category(title: "Category 0")
categories.append(category0)
let category1 = Category(title: "Category 1")
categories.append(category1)
// [Category(title: "Category 0", subcategories: []), Category(title: "Category 1", subcategories: [])]
var cat = categories[0]
cat.subcategories.append(SubCategory(title: "Sub0", value0: 1, value1: 2))
cat.subcategories.append(SubCategory(title: "Sub1", value0: 3, value1: 4))
categories[0] = cat
// [Category(title: "Category 0", subcategories: [SubCategory(title: "Sub0", value0: 1, value1: 2), SubCategory(title: "Sub1", value0: 3, value1: 4)]), Category(title: "Category 1", subcategories: [])]
var cat = categories[0]
cat.title = "New title"
categories[0] = cat
// [Category(title: "New title", subcategories: []), Category(title: "Category 1", subcategories: [])]
Upvotes: 0
Reputation: 23596
You can use a dictionary [String : [String : (Int, Int)]]
let dictionary: [String : [String : (Int, Int)]] = [
"Title1" : [
"subcat1" : (5, 10),
"subcat2" : (7, 15)
],
"Title2" : [
"subcat3" : (3, 6),
"subcat4" : (7, 8),
"subcat5" : (12, 14)
]
]
To get the tuple of integers (Int, Int)
under a category and subcategory, you can use
let tuple: (Int, Int) = dictionary[title]![subcategory]!
But, this uses forced unwrapping using the !
. Instead, a safer way to do it that won't cause your app to crash would be
let tuple: (Int, Int)? = dictionary[title]?[subcategory]
Then, to get the values in the tuple you could use
let val1: Int? = tuple?.0
let val2: Int? = tuple?.1
To just set the value 0 instead of nil when the value does not exist, you could use the ??
operator
let val1: Int = tuple?.0 ?? 0
let val2: Int = tuple?.1 ?? 0
If you wanted to loop through all the values, it could be done with
for title in dictionary.keys{
for subcategory in dictionary[title]!.keys{
//we can force unwrapping because we are sure the
//value will not be nil, because we are looping
//through the keys of the dictionary
let value1: Int = dictionary[title]![subcategory]!.0
let value2: Int = dictionary[title]![subcategory]!.1
//use title, subcategory, value1, and value2 as you please
}
}
Setting a value is as simple as
dictionary["newOrExistingTitle"]["newOrExistingSubcategory"] = (num1, num2)
For example
dictionary["Title1"]["subcat2"] = (8, 2)
Upvotes: 1