-2

I am coding a Swift class that builds a dictionary when instantiating it, plus the possibility of adding pairs of key - value, but once done the problem is I can not access the individual pairs I add, so there must be a problem somewhere I can not detect, please help

class MyDictionary {

var dictionary = ["":""]

init() {
}

func addPair(key: String, value: String) {
    //dictionary["key"] = "value"
    dictionary.updateValue(value, forKey: key)
}

}

// just to compare... this one works
    var dict = ["one": "abc"]
    dict["two"] = "efg"
    print(dict["two"]!)

    let myDictionary = MyDictionary()
    myDictionary.addPair(key: "key1", value: "value1")
    print(myDictionary)

    //print(myDictionary["key1"])  //Does not work
Fausto Checa
  • 163
  • 13

3 Answers3

3

Change

print(myDictionary["key1"])

To

print(myDictionary.dictionary["key1"])
matt
  • 515,959
  • 87
  • 875
  • 1,141
1

I a assuming you want to create a custom dictionary, because you'd like to check (maybe in future) if the values to be added as as a key-pair are acceptable or so.

Anyway, if you want to have a custom dictionary class to act as a wrapper over the system Dictionary class, I'd advice to make the dictionary property private (so no outsiders can access and modify it directly), and add an additional method for getting the value for a key (if such key exists):

class MyDictionary {

    private var dictionary = ["":""]

    init() {
    }

    func addPair(key: String, value: String) {
        dictionary.updateValue(value, forKey: key)
    }

    func valueForKey(_ key: String) -> String? {
        if let valueForKey = dictionary[key] {
            return valueForKey
        }
        return nil
    }
}

This is how would you use it:

let myDictionary = MyDictionary()
myDictionary.addPair(key: "key1", value: "value1")

if let valueForKey = myDictionary.valueForKey("key1") {
    print(valueForKey)
}

If you really want to get the value the way you mentioned it's not working, you'll need to implement a subscript, because MyDictionary is a custom class and does not have one yet:

class MyDictionary {

    private var dictionary = ["":""]

    /* more code */

    func valueForKey(_ key: String) -> String? {
        if let valueForKey = dictionary[key] {
            return valueForKey
        }
        return nil
    }

    subscript(_ key: String) -> String? {
        get {
            return valueForKey(key)
        }
    }
}

This is how would you use the subscript:

let myDictionary = MyDictionary()
myDictionary.addPair(key: "key1", value: "value1")

if let valueForKey = myDictionary["key1"] {
    print(valueForKey)
    print(myDictionary["key1"]!)
}

Note that myDictionary["key1"] returns an Optional String, or String?, therefore you'd have to force unwrap the value in order for the print() method not to complain. Since we do it inside the if let statement - we know myDictionary["key1"] is not nil, and myDictionary["key1"]! must be some valid String object.

See more here: https://docs.swift.org/swift-book/LanguageGuide/Subscripts.html

ppalancica
  • 4,236
  • 4
  • 27
  • 42
0

To be able to use your syntax add key subscription support (getter and setter).

class MyDictionary {

    var dictionary = ["":""]

    init() {
    }

    func addPair(key: String, value: String) {
        dictionary.updateValue(value, forKey: key)
    }

    subscript(_ key: String) -> String? {
        get { return dictionary[key] }
        set { dictionary[key] = newValue }
    }
}

let myDictionary = MyDictionary()
myDictionary.addPair(key: "key1", value: "value1")
print(myDictionary["key1"]!)

You could extend the class as generic to use it with different types. The subscription setter makes addPair even redundant.

class MyDictionary<K : Hashable, V> {

    var dictionary = [K:V]()

    subscript(_ key: K) -> V? {
        get { return dictionary[key] }
        set { dictionary[key] = newValue }
    }
}

let myDictionary = MyDictionary<String,String>()
myDictionary["key1"] = "value1"   
print(myDictionary["key1"]!)
vadian
  • 274,689
  • 30
  • 353
  • 361