Just a coder
Just a coder

Reputation: 16720

How to make a Swift Dictionary that hold specific values?

Usually I create my swift dictionary like so:

var myDict: [String: String]

But how do I create a Dictionary that can have as values, only a String or a Bool?

If I declare the dictionary like the following code

var myDict: [String: Any]

then my array would now be able to hold any object which I do not want. Is there any way to declare the Dictionary to only accept String and Bool value types?

[EDIT] - Use case is: i need to have a dictionary of Keys and values. But i only want to values to be restricted to be either Strings or Bools. Nothing else. The goal is to eventually use this Dictionary to convert to a JSON format to send to some server. Based on the answers below, are my only options either enums or classes/structs? I was wondering if there was a way to make the Bool and the String conform to some protocol?

The idea is to maybe declare the Dictionary like so

var myDict : [String: stringOrBool]

And to fill in the dictionary like this

myDict["firstKeyStringValue"] = "my first string value" // This should work
myDict["firstKeyBoolValue"] = true // This should work
myDict["someOtherKey"] = 123 // This should fail

Edit 2 Based on the answers below i chose the protocol approach because it was easier on the syntax. But as Catfish mentioned below in the comments, it may take up a bit more memory.

Upvotes: 3

Views: 702

Answers (3)

swift nub
swift nub

Reputation: 2937

protocol StringOrBool {
}

extension Bool: StringOrBool {
}

extension String: StringOrBool {
}

var myDict: [String : StringOrBool] = [:]

myDict["testKey"] = "sd"   // works
myDict["testKey2"] = false // works
myDict["testKey2"] = 2     // fails

Upvotes: 6

Luca Angeletti
Luca Angeletti

Reputation: 59496

This solution is based on the answer by Catfish_Man, I just made it generic.

With this enum

enum XORWrapper<A,B> {
    case Value0(A)
    case Value1(B)
}

you can declare a value that does wrap a value of 2 generic types (e.g. String and Bool).

let boolOrString: XORWrapper<String, Bool>

Then you can populate it with the first Type (e.g. a String)

boolOrString = XORWrapper.Value0("Hello world")

or with the second one (e.g. a Bool)

boolOrString = XORWrapper.Value1(true)

Upvotes: 2

Catfish_Man
Catfish_Man

Reputation: 41801

You could do something like

enum StuffThatGoesInMyDictionary {
    case Text(String)
    case Boolean(Bool)
}

and then have your dictionary be

var myDict: [String : StuffThatGoesInMyDictionary]

Upvotes: 7

Related Questions