+3 votes
var dictionary = {1 = 2, 3 = 4}
var new_element = {5 = 6, 7 = 8}
dictionary.update(new_element) (??)

Is there a way to add new elements to the existing dictionary I'm missing?

asked Sep 16, 2016 in Engine by Maverik (44 points)

3 Answers

+1 vote
dictionary[5] = 6
dictionary[7] = 8


var dict = {A=1,B=2,C=3}
dict['D'] = 4
dict['E'] = 5
print(dict)
>> (A:1), (B:2), (C:3), (D:4), (E:5)

I don't believe godot has a dictionary merge method.

answered Sep 16, 2016 by txzeenath (16 points)

Thats kind of a shame. Manual input step by step is not exactly optimal for me.

Honestly, I don't think GDScript needs to expose that just for the sake of economizing two lines. You can update the dictionary with just this:

static func merge_dir(target, patch):
    for key in patch:
        target[key] = patch[key]

That actually helps, thank you.

On the other note, it does not quite work when merging dictionaries have same subdictionaries.

This version should work with sub-dictionaries:

static func merge_dir(target, patch):
    for key in patch:
        if target.has(key):
            var tv = target[key]
            if typeof(tv) == TYPE_DICTIONARY:
                merge_dir(tv, patch[key])
            else:
                target[key] = patch[key]
        else:
            target[key] = patch[key]

Yep, seems to be working, except for has_key should be just key. Thank you!

Ah, nope, it should be has.

Right, meant to say that.

0 votes

There is no Update() method. The function for merging dictionaries has to be written.
When merging , the question which should be answered is:
"What to do if the destination dictionary already has a key which exists in the source?"

Typically, we would override the destination existing value unless the key points to the sub-dictionaries in both dictionaries. In such case we can merge the sub-dictionaries.

Testing dictionaries and the results :

var dest = {1:"a", 2:"b", 7:"e" }     
var source = {7:{5:"e", 6:"f"}, 4:{4:"d",8:[1,2,3]}}
#  result:
# (1:a), (2:b), (4:(4:d), (8:[1, 2, 3])), (7:(5:e), (6:f))

var dest1 = {1:"a", 2:"b", 7:{5:"e", 6:"f"} }
var source1 = {7:"c", 4:"d"}
#  result:
#  merge_dict = (1:a), (2:b), (4:d), (7:c)

var dest2 = {1:"a", 2:"b", 7:{5:"e", 6:"f"} }
var source2 = {7:{66:"c", 77:"g"}, 4:"d"}
#  result:
# (1:a), (2:b), (4:d), (7:(5:e), (6:f), (66:c), (77:g))

var dest3 = {1:"a", 2:"b", 3:{8:{12:"33", 10:"55"}, 9:"44"}}
var source3 = {4:"d", 3:{11:"abc",14:"abcd"}, 10:"67"}
# result
# (1:a), (10:67), (2:b), (3:(11:abc), (14:abcd), (8:(10:55), (12:33)), (9:44)), (4:d)

static func merge_dict(dest, source):
    for key in source:                     # go via all keys in source
        if dest.has(key):                  # we found matching key in dest
            var dest_value = dest[key]     # get value 
            var source_value = source[key] # get value in the source dict           
            if typeof(dest_value) == TYPE_DICTIONARY:       
                if typeof(source_value) == TYPE_DICTIONARY: 
                    merge_dict(dest_value, source_value)  
                else:
                    dest[key] = source_value # override the dest value
            else:
                dest[key] = source_value     # add to dictionary 
        else:
            dest[key] = source[key]          # just add value to the dest

Test

func _ready():

    merge_dict(dest, source)
    print(dest)

    merge_dict(dest1, source1)
    print(dest1)

    merge_dict(dest2, source2)
    print(dest2)

    merge_dict(dest3, source3)
    print(dest3)
answered Aug 20, 2018 by sg7 (20 points)
–1 vote

Just like many other scripting languages

var PlayerData = {}
PlayerData["HELLO"] = "hi"
print(PlayerData)

{
"HELLO":"hi"
}

See its quiet simple.

answered Feb 21 by Merlin1846 (172 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.