How to Merge Two Dictionaries or Arrays in GDScript (Godot Engine)?

Viewed 812

Say I have two Dictionaries (or could be Arrays), each having sub-dictionaries (or sub-arrays):

var dict_A = {'a': 1, 'sub_dict':  {'hello': 'world', 'quick': 'fox'}}
var dict_B = {'b': 2, 'sub_dict': {'hello': 'godot'}}

Is there a builtin method in GDScript to merge them, including the sub-dictionaries or sub-arrays?

Expected result would be:

merge_dict(dict_A, dict_B)

# {'a': 1, 'b': 2, 'sub_dict':  {'hello': 'godot', 'quick': 'fox'}}
1 Answers

There's no builtin method in GDScript for that, but you can use the following functions (find usage examples, unit tests, and more on this Github gist):

Observation: when using deep_merge=true with merge_array, all sub-dictionaries and sub-arrays must be JSON serializable.

func merge_array(array_1: Array, array_2: Array, deep_merge: bool = false) -> Array:
    var new_array = array_1.duplicate(true)
    var compare_array = new_array
    var item_exists

    if deep_merge:
        compare_array = []
        for item in new_array:
            if item is Dictionary or item is Array:
                compare_array.append(JSON.print(item))
            else:
                compare_array.append(item)

    for item in array_2:
        item_exists = item
        if item is Dictionary or item is Array:
            item = item.duplicate(true)
            if deep_merge:
                item_exists = JSON.print(item)

        if not item_exists in compare_array:
            new_array.append(item)
    return new_array


func merge_dict(dict_1: Dictionary, dict_2: Dictionary, deep_merge: bool = false) -> Dictionary:
    var new_dict = dict_1.duplicate(true)
    for key in dict_2:
        if key in new_dict:
            if deep_merge and dict_1[key] is Dictionary and dict_2[key] is Dictionary:
                new_dict[key] = merge_dict(dict_1[key], dict_2[key])
            elif deep_merge and dict_1[key] is Array and dict_2[key] is Array:
                new_dict[key] = merge_array(dict_1[key], dict_2[key])
            else:
                new_dict[key] = dict_2[key]
        else:
            new_dict[key] = dict_2[key]
    return new_dict

This code is licensed under BSD 3-Clause License | Copyright 2022 Hackverse.org

Related