Multidimensional Dictionaries Possible in Swift

Multidimensional dictionaries possible in Swift?

Yes, in Swift that would be:

let myArray = [
"motorcycles": ["Honda", "Ducati", "Yamaha"],
"cars": [
"sedans": ["Jetta", "Taurus", "Impala"],
"sport" : ["Porsche", "Ferarri", "Corvette"],
"trucks" : [
"shortbed" : ["Ford F150", "Dodge Ram 1500"],
"longbed" : [
"standardCab":["Ford F350", "Dodge Ram 2500"],
"crewCab":["Ford F350", "Dodge Ram 2500"]
]
]
]
]

Reading values from such a structure can be a bit difficult though, since Swift has difficulty discerning the types. To get the standardCab vehicles, you can do:

if let trucks = myArray["cars"]?["trucks"] as? [String:AnyObject] {
if let standardCab = trucks["longbed"]?["standardCab"] as? [String] {
println(standardCab)
}
}

Appending Multidimensional Dictionary

It seems like you're trying to bypass Swift's type system instead of working with it. Instead of using AnyObject, you should be trying to use the exact type you want for the value of that dictionary. In this case it looks like you want something like [Int: [String: [String: String]]] (although, like @EricD said in the comments, you should probably be using a struct instead, if at all possible).

Here's a quick (static) example similar to the code in your question:

var items = [Int: [String: [String: String]]]()
let idsAndDetails = ["id2": ["key3": "value3"]]

let index = 3
items[index] = ["id1": ["key1": "value1", "key2": "value2"]]

let result = "id2"
if let itemDetails = idsAndDetails[result] {
items[index]?[result] = itemDetails
}

At the end of that, items will be:

[3: ["id1": ["key1": "value1", "key2": "value2"], "id2": ["key3": "value3"]]]

The ? in items[index]?[result] tells Swift to make sure items[index] is non-nil before attempting to execute the subscript method. That way, if you try to update an index that doesn't exist in items you don't cause a crash.

Swift 2 dimensional dictionary of any objects

There's nothing wrong in the type - you are just using the wrong syntax for initializing it:

var mediaCardSet = [Int: [String: Any]]()
^

If instead you don't want to initialize, just declare the variable/property, you don't need the parenthesis at the end:

var mediaCardSet: [Int: [String: Any]]

Navigation using multi dimensional dictionary in swiftui

SwiftUI does not work with Any type, so as soon as you detect your data type you have to cast it to let SwiftUI know how to proceed.

Here is a fixed part of original code. Tested with Xcode 11.4 / iOS 13.4

if isStringList(key:key, dict: dict) {
List{
// verified detected [String], so cast it explicitly to
// give chance to check types here
ForEach(dict[key] as! [String], id: \.self) { content in
HStack{
Text(content)
}
}
}
}

Get value from multidimensional array in swift

You need to look into how to unwrap optionals. For example, what you are trying to do could be done either of these two ways:

Force unwrapping:

print(words["English"]![0])

Safe unwrapping:

if let hello = words["English"]?[0]{
print(hello)
}

Initialize multidimensional array in swift

You could simply use the following syntax :

var results = [String: [String: String]]()

Swift two dimensional dictionary error

Looking up a value in a dictionary returns an optional (since that key may not exist.) This epression:

locale[lang]["create"]

Should be

locale[lang]!["create"]

Instead.

Note that that code will crash if there is not an entry for the current language in your dictionary. It would be safer to use optional binding:

if let createButtonTitle = locale[lang]?["create"]
{
let createButton = UIBarButtonItem(
title: createButtonTitle,
style: UIBarButtonItemStyle.Plain,
target: self,
action: "createAction:")
self.navigationItem.rightBarButtonItem = createButton
}

How to access deeply nested dictionaries in Swift

When working with dictionaries you have to remember that a key might not exist in the dictionary. For this reason, dictionaries always return optionals. So each time you access the dictionary by key you have to unwrap at each level as follows:

bugsDict["ladybug"]!["spotted"]!["red"]!++

I presume you know about optionals, but just to be clear, use the exclamation mark if you are 100% sure the key exists in the dictionary, otherwise it's better to use the question mark:

bugsDict["ladybug"]?["spotted"]?["red"]?++

Addendum: This is the code I used for testing in playground:

var colorsDict = [String : Int]()
var patternsDict = [String : [String : Int]] ()
var bugsDict = [String : [String : [String : Int]]] ()

colorsDict["red"] = 1
patternsDict["spotted"] = colorsDict
bugsDict["ladybug"] = patternsDict

bugsDict["ladybug"]!["spotted"]!["red"]!++ // Prints 1
bugsDict["ladybug"]!["spotted"]!["red"]!++ // Prints 2
bugsDict["ladybug"]!["spotted"]!["red"]!++ // Prints 3
bugsDict["ladybug"]!["spotted"]!["red"]! // Prints 4

How to make a dictionary with a 2D Array as Value?

Your dictionary should have an array of string arrays as value.

var lst1 = ["val1", "val2", "val3"]
var lst2 = ["vala", "valb", "valc"]
var lst3 = ["test1", "test2", "test3"]
var lst4 = ["testa", "testb", "testc"]

var dict: [String: [[String]]] = [:]

To store values, you should have a method which stores the list or appends the list with the existing list(s) if a value already exists.

func saveToDictionary(list: [String], withKey key: String) {
dict[key, default: []].append(list)
}

saveToDictionary(list: lst1, withKey: "key1")
saveToDictionary(list: lst2, withKey: "key1")

print(dict)

Edit: Improved the answer after referring to this.



Related Topics



Leave a reply



Submit