How do I duplicate a dictionary in godot 3.0 alpha 2.

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By stubbsy345
:warning: Old Version Published before Godot 3 was released.

I want to capy my dictionary into another variable and have it not effect the original variable. Currently when i do:

dict_new = my_dict

If I adapt anything in dict_new it also impacts my_dict. Is there a way of duplicating the data rather than just referencing it?

:bust_in_silhouette: Reply From: hnuqweasd

I had this issue before and I couldn’t find an obvious way to do it. I ended up making a function, e.g:

extends Node

func _ready():
	
	var my_dict = { "blood":"red", "ink":"black" }
	var my_other_dict = {}
	
	clone_dict(my_dict, my_other_dict)

	my_dict["slime"] = "green"
	my_other_dict["sky"] = "blue"
	
	print("my dict:", my_dict)
	print("my other dict:", my_other_dict)
	
func clone_dict(source, target):
	for key in source:
		target[key] = source[key]

Output is:

my dict:(blood:red), (ink:black), (slime:green)
my other dict:(blood:red), (ink:black), (sky:blue)

Let me know if you find a better way :slight_smile:

So my issue with this is I have a rather large dictionary which contains dictionaries within dictionaries. So this function won’t make a completely unique dictionary for me like it would if it just contained key:value pairs. Thanks for your reply though. Surely there is some way to make a dictionary unique in a straightforward manner.

stubbsy345 | 2017-11-02 21:36

:bust_in_silhouette: Reply From: Zylann

There is no straightforward manner unfortunately. This is because there are multiple ways of cloning such object. You could do a shallow copy, a deep copy, and even the objects you store in it themselves would need to support copy (if it’s nodes? If it’s resources? If it’s a custom class?). And what would even happen if by mistake, your dictionary contains a reference to itself? (circular reference).

But I can give you something that copies recursively, should work for pure data and maybe on some Objects:

static func deep_copy(v):
	var t = typeof(v)
	
	if t == TYPE_DICTIONARY:
		var d = {}
		for k in v:
			d[k] = deep_copy(v[k])
		return d
		
	elif t == TYPE_ARRAY:
		var d = []
		d.resize(len(v))
		for i in range(len(v)):
			d[i] = deep_copy(v[i])
		return d
	
	elif t == TYPE_OBJECT:
		if v.has_method("duplicate"):
			return v.duplicate()
		else:
			print("Found an object, but I don't know how to copy it!")
			return v
	
	else:
		# Other types should be fine,
		# they are value types (except poolarrays maybe)
		return v

Just make sure your data doesn’t contain cycles, or this will hang forever :stuck_out_tongue:

Example:

var demo = {
	hello = 42,
	world = "yolo",
	sub = {
		x = PI,
		y = 12345
	},
	list = [
		"one",
		"two", 
		"three"
	]
}

print(demo)
var dup = deep_copy(demo)
print(dup)

Thanks for this

jtarallo | 2020-07-19 16:38

Thanks, really helpful!

Juha Hollanti | 2020-10-17 10:09

:bust_in_silhouette: Reply From: TheSecurityDev

I know this is old, but now you can use dict_new = my_dict.duplicate().

And if you have Dictionaries or Arrays within the Dictionary, and you want to duplicate those as well, use my_dict.duplicate(true).

this is the actually best answer lol

Castro1709 | 2021-07-19 23:03