Copying Dictionaries
Part of the Logic & Flow section of Coddy's GDScript journey. Lesson 22 of 78.
Assigning a dictionary to another variable does not copy it. Both variables refer to the same dictionary, so a change through one shows through the other:
var template := {"type": "slime", "hp": 30}
var enemy := template
enemy["hp"] = 10
print(template["hp"]) # 10duplicate() creates a new dictionary with the same pairs. Changing the copy leaves the original alone:
var original := {"type": "slime", "hp": 30}
var copy := original.duplicate()
copy["hp"] = 99
print(original["hp"]) # 30duplicate() makes a shallow copy: the copy has its own pairs, but a value that is an array or a dictionary is still shared between the two:
var hero := {"stats": {"hp": 100}, "items": ["sword"]}
var clone := hero.duplicate()
clone["stats"]["hp"] = 1
clone["items"].append("shield")
print(hero){ "stats": { "hp": 1 }, "items": ["sword", "shield"] }Pass true for a deep copy: duplicate(true) also copies every array and dictionary inside, so the two share nothing:
var twin := hero.duplicate(true)
twin["stats"]["hp"] = 50
print(hero["stats"]["hp"]) # 1A shallow copy is enough when every value is a number, a string or a boolean. As soon as a value is an array or a dictionary, use duplicate(true). Arrays work the same way: grid.duplicate(true) copies a 2D array together with its rows.
Challenge
EasySpawn a wave of enemies from a template. The dictionary template is given. The program reads two whole numbers, one per line: how many enemies to spawn (n) and an hp bonus.
For each enemy number i from 1 to n:
- Make a copy of
templatethat shares nothing with it. - Add the key
"id"with the valuei. - Add
bonus * ito the"hp"inside"stats". - If it is the last enemy, append
"crown"to its"loot". - Print the enemy.
Finally, print Template: followed by the template, which must be unchanged. For the inputs 2 and 10, the output is:
{ "type": "slime", "stats": { "hp": 40, "speed": 2 }, "loot": ["gel"], "id": 1 }
{ "type": "slime", "stats": { "hp": 50, "speed": 2 }, "loot": ["gel", "crown"], "id": 2 }
Template: { "type": "slime", "stats": { "hp": 30, "speed": 2 }, "loot": ["gel"] }Try it yourself
extends Node
func _ready():
var template := {"type": "slime", "stats": {"hp": 30, "speed": 2}, "loot": ["gel"]}
var n := int(OS.read_string_from_stdin())
var bonus := int(OS.read_string_from_stdin())
# Spawn and print the n enemies
# Print the template
pass
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Logic & Flow
1Strings In Depth
String MethodsSearching in StringsReplace and TrimSplit and JoinRecap - Username Check4Dictionaries Part 2
Nested DictionariesArrays of DictionariesMerging DictionariesCopying DictionariesRecap - Frequency Counter2Advanced Decision Making
Match With VariablesMatch GuardsArray PatternsDictionary PatternsMembership ChecksRecap - Command Parser5Contact Book Application
Display MenuAdd Contact8Student Records Manager
Project OverviewAdd Student3Multi-dimensional Arrays
2D Arrays BasicsAccessing 2D Array ElementsNested Loops with 2D ArraysRecap - 2D ArraysJagged ArraysCommon 2D Array PatternsRecap - Game Board6Sets with Dictionaries
What is a Set?Dictionary as a SetAdding and RemovingUnion and IntersectionSet DifferenceRecap - Remove Duplicates9Advanced Data Aggregation
Summing ValuesFinding Minimum and MaximumCustom SortingRecap - Dictionary SorterPractice on your own: Online GDScript compiler