-1

I want to add another dictionary entry to a dictionary in swift e.g.

let a: [String: Any] = ["Test": 1, "good":false]
let b = a + ["hello": "there"]
print(b)

(Sorry if + looks crazy here, as that's how Kotlin achieves this. I'm more familiar with Kotlin than Swift.)

But I get the error Binary operator '+' cannot be applied to two '[String : Any]' operands

I can't use updateValue too

let a: [String: Any] = ["Test": 1, "good":false]
let b = a.updateValue("hello": "there")
print(b)

It will error stating Cannot use mutating member on immutable value: 'a' is a 'let' constant

I can do it by an extension function as per proposed https://stackoverflow.com/a/26728685/3286489

but it looks overkill.

let b = a.merge(dict: ["hello": "there"])
print(b)


extension Dictionary {
    func merge(dict: Dictionary<Key,Value>) -> Dictionary<Key,Value> {
        var mutableCopy = self
        for (key, value) in dict {
            // If both dictionaries have a value for same key, the value of the other dictionary is used.
            mutableCopy[key] = value
        }
        return mutableCopy
    }
}

Is there a simple operator I can just add another entry to it to for a new dictionary?

Note: I'm not referring to append as per How to append elements into a dictionary in Swift?, as I receive an immutable dictionary let that I need to add another entry to it.

Elye
  • 53,639
  • 54
  • 212
  • 474

1 Answers1

1

There is a built-in merging(_:uniquingKeysWith:) function on Dictionary that does exactly what you need.

let dictionary = [1:1]
let otherDictionary = [1:2, 2:3]
// This will take the values from `otherDictionary` if the same key exists in both
// You can use `$0` if you want to take the value from `dictionary` instead
let mergedDict = dictionary.merging(otherDictionary, uniquingKeysWith: { $1 })

If you want, you can easily define a + operator for Dictionary that uses the above function.

extension Dictionary {
    static func + (lhs: Self, rhs: Self) -> Self {
        lhs.merging(rhs, uniquingKeysWith: { $1 })
    }
}

let addedDict = dictionary + otherDictionary
Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116
  • Thanks. I guess I can use that. It does look a bit too long though, as I really have just one entry to add to it, not really a dictionary. Is there a shorter way? In Kotlin (I'm more familiar with Android), I can use `+` operator to produce a new map (i.e. dictionary in Swift). If there's none, I'll use this one then. – Elye Jul 30 '20 at 09:52
  • 1
    @Elye there's no built-in operator for this, since there's no generic approach for what value should be assigned if a key exists in both dictionaries. However, you can easily implement your own `+` operator, check my updated answer – Dávid Pásztor Jul 30 '20 at 09:55
  • 1
    Nice one, Love the `+` custom operator. Thanks!! – Elye Jul 30 '20 at 09:56
  • I'm just curious why my question got downvoted. I did my research, and use my Kotlin knowledge to explore for solutions. Indeed there's no direct solution like what Kotlin has (which mislead me to think there's so solution out there). Do pardon my naive and ignorant in Swift language. – Elye Jul 30 '20 at 10:01
  • 1
    @Elye not sure, I wasn't the one who downvoted your question, it looks like a good quality question to me – Dávid Pásztor Jul 30 '20 at 10:03
  • Thanks, @Dávid Pásztor! – Elye Jul 30 '20 at 10:04