I'm trying to copy an array, then altering the copy (mainly removing elements), but the copy is altering the original as well.

What I've tried

  • I've tried using the duplicate feature for arrays (setting deep as TRUE), but it's not creating unique instances.
  • I've tried using a loop and appending each element from the array individually, but they're still referencing the original.

Only thing I could think maybe is messing with it is that it's coming from an array that is within a Dictionary, if that makes a difference.

Has anyone had this issue before? Or does anyone know if there's a way to do it properly?

  • xyz replied to this.

    pyxelwyxel The proper way is to explicitly duplicate contained objects. If you enable deep copy for duplicate() it will only deep copy nested arrays/dicts, but it will not make copies of other objects.

      xyz
      How would I explicitly duplicate contained objects/array elements?

      • xyz replied to this.

        pyxelwyxel Node and Resource base classes both have the duplicate() method.
        You can iterate manually and push duplicates into a new array. But here's a fancy way of doing it using Array::map() and a lambda callable (only in Godot 4):

        var a = [ Node.new(), Node.new() ]
        var b = a.map( func(x): return x.duplicate() )
        print(a)
        print(b)

          xyz
          Sorry, I forgot to mention my array elements are Strings, not Nodes. I haven't been able to find a way for duplicating Strings in the docs. How would I go about duplicating String variables? Or should I approach the problem differently? Would it be better to store an array of integer indexes of the original array?

          • xyz replied to this.

            pyxelwyxel Strings contained within an array will be duplicated when the array is duplicated. So will be all other built-in types that are passed/assigned by value. Only objects that are passed/assigned by reference need explicit duplication.

            Btw strings are duplicated simply by assignment:

            var s = "A"
            var s2 = s # s2 is a duplicate

              xyz
              Okay, thanks, that's good to know. I had a feeling that was how they worked, but it hasn't been working for this function. Do variables from Global Nodes/Singletons act differently?

              In the debugger the array elements do look like Strings so it doesn't look like they're some other type of variable/object. I tried printing their type and it says they're of type String (4). I also tried reassigning each array element type as a String but it also isn't making them unique.

              • xyz replied to this.

                xyz
                I've tried these
                GameData is the Singleton. It has a bunch of loaded in JSON data converted into dictionaries. "attacks" is an array of Strings.

                var attack_card_list = []
                var current_weapon_attacks = GameData.weapon_type[current_weapon_type]["attacks"].duplicate(true)
                for i in range(0, current_weapon_attacks.size()):
                	attack_cards_list.append(current_weapon_attacks[i])
                var attack_card_list = []
                var current_weapon_attacks = GameData.weapon_type[current_weapon_type]["attacks"].duplicate(true)
                attack_cards_list.append_array(current_weapon_attacks.duplicate(true))

                and initially it was just something like this

                var attack_card_list = []
                var current_weapon_attacks = GameData.weapon_type[current_weapon_type]["attacks"]
                attack_card_list = current_weapon_attacks
                • xyz replied to this.

                  pyxelwyxel Third snippet just makes a new reference to the array. That's probably not what you want. The first two should be ok if you're indeed dealing with a flat string array. Since this is json, it acually might not be the case. We'll probably need to see that json file.

                  However you did not demonstrate the problem. What makes you think your copied strings are "not unique"?

                    xyz
                    The problem appears when editing any of the array elements. If I remove an element from the new array, it removes the same element from the original.

                    There's nothing strange in the JSON data or the original JSON file. And the imported dictionaries, their arrays, and variables are functioning as expected, except in this specific instance.

                    I'm just going to try experimenting with scope or making the Dictionary not come from JSON to see if that alters anything and report back here, because it seems from your understanding and mine that it should be working.

                    • xyz replied to this.

                      pyxelwyxel If I remove an element from the new array, it removes the same element from the original.

                      This means you have not made an array duplicate but simply created a new reference to the same array.

                      If you can, make a minimal project that demonstrates the problem and post it here. That'll be the quickest way to resolve this.

                        xyz
                        Welp, it seems I have solved the problem. Turns out the issue was the usual one, bugs in code (though not in the script I was working on). 😅

                        Thanks for helping me go through the problem.

                        I made a new project, eventually got it working, and didn't have the same problem. So, I went back to my old project and searched around. Turns out was editing the arrays in a different script where I didn't duplicate them as I built them before learning about needing to duplicate, but I was only noticing the results in the script I was working on.

                        • xyz replied to this.
                          pyxelwyxel changed the title to [SOLVED] Duplicate Array not unique (Godot 3.5.1) .

                          pyxelwyxel Turns out the issue was the usual one, bugs in code

                          Them pesky bugs, eh? 😃