Attention | Topic was automatically imported from the old Question2Answer platform. | |
Asked By | JTJonny | |
Old Version | Published before Godot 3 was released. |
why does this work in some places: graph_dict[keys[i]].erase(vert)
, but other places it does nothing (doesn’t even crash) .
I have to replace it with something like this:
var neighbors_to_modify = graph_dict[keys[i]]
neighbors_to_modify.erase(vert)
graph_dict[keys[i]] = neighbors_to_modify
In the second code sample, the last line is not needed because dictionaries and arrays are reference types.
Other than that, I don’t know how to answer the problem. What’s your definition of “not working”? Did you create dictionaries and arrays by writing Array()
or Dictionary()
by any chance? (instead of []
or {}
)
Zylann | 2017-09-27 00:20
I use and {}. I was just wondering why I couldn’t use graph_dict[keys[i]].erase(vert)
. It seemed to not change the reference at all. I Also tried it without the last part and it doesn’t work, maybe it has something to do with it being so nested.
JTJonny | 2017-09-27 04:06
To find your problem, your example should contain data. We have no idea what is in graph_dict, keys or which value/type “vert” has.
Example (untested):
var keys = ["a","b","c"]
var graph_dict= { "a": {"keyA":"abc", "keyB":123},
"b": {"keyA":"y", "keyB":42},
"v": {"keyA":"x", "keyB":123}}
graph_dict[keys[0]].erase("keyB")
wombatstampede | 2017-09-27 08:56
The graph_dict is a Dictionary of Vector2s that calls an Array of Vector2s
{Vector2:[Vector2, Vector2]}
Here is the complete function:
func remove_verts_from_dict_graph(graph_dict, remove_vert_array):
for vert in remove_vert_array:
graph_dict.erase(vert)
var keys = graph_dict.keys()
for vert in remove_vert_array:
for i in range(graph_dict.size()):
# this does not work graph_dict[keys[i]].erase(vert)
var neighbors_to_modify = graph_dict[keys[i]]
neighbors_to_modify.erase(vert)
graph_dict[keys[i]] = neighbors_to_modify
return graph_dict
JTJonny | 2017-09-27 20:03
Ok, if I get it right then you use a Vector2 as Key for erase?
Actually, I never used anything other than strings as keys in dictionaries so my experience here is a bit limited.
But if that is true, then you basically use a vectoy consisting of 2 float values for comparison (in erase). And as you might know, comparing floats with == is risky. Normally, you compare floats like this: abs(float2-float1) < margin_of_error
. Where margin_of_error is a low value depending on your typical number range (i.e. 0.0001). With Vector2, it may be something like (Vector2-Vector1).length() < margin_of_error
.
#1:
You can check, if this “comparison” problem is actually the problem here. Simply output the result of dictionary.has(key) before using erase and you’ll know if there’s actually a match to erase.
#2:
You could use a key which is comparable. I.e. use a string-representation with rounded values. Naturally, this uses additional CPU.
wombatstampede | 2017-09-28 06:30
Note that it should be fine if the vectors contain integer positions, and is actually a good solution to implement a spatial hash in GDScript. But of course you need to be aware of the fact numbers are still floats, and they will start to be off above some limit.
Zylann | 2017-09-28 18:34
Thanks for the info everyone. I don’t think its a comparison problem. These vectors don’t change, they only get deleted and reloaded as the exact same value. Once their made I never reference anything again. The longer code works just fine, I was just wonder about why the shorter version doesn’t. I think I’ll hide this question soon.
JTJonny | 2017-09-28 21:52