jhelst
jhelst

Reputation: 15

Organizing multiple types data in arrays swift 2

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

Answers (2)

Luca Angeletti
Luca Angeletti

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.

Adding a 2 categories

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: [])]

Adding a 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: [])]

Changing the Category Title

var cat = categories[0]
cat.title = "New title"
categories[0] = cat

// [Category(title: "New title", subcategories: []), Category(title: "Category 1", subcategories: [])]

Upvotes: 0

Jojodmo
Jojodmo

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

Related Questions