Modifying Values From A Dictionary

Hi, I'm working on pulling data from a dictionary.  However, when I modify the variable 'myarray', It's modifying the dictionary as well, and it's driving me crazy.  Any advice on how I can fix this?

var storagedict = {"A"=>1,"B"=>2,"C"=>[]};
var myarray = storagedict.get("C");
myarray.add("D");
System.println(myarray); // Prints: [D]
System.println(storagedict);
//Prints: {A=>1, B=>2, C=>[D]}, when I really want it to stay: {A=>1, B=>2, C=>[]}.

Thanks!

SirLancelot

  • I was suberised recently too such strange behaviour but not the same case:)

    It's 'normal' in Mokey C, read:

    https://forums.garmin.com/developer/connect-iq/f/discussion/277902/pointers-in-monkey-c---bug-or-by-design

  • Thanks for your help! I ended up just creating a new blank array and using .addAll to fill the new array with the old contents. Thanks again for the info!

  • Not to beat a dead horse, but it's no different than languages like Python and JavaScript.

    e.g. JavaScript:

    let x = { A: 1, B: 2, C: [] };
    let array = x.C;
    array.push("D");
    console.log(JSON.stringify(x, null, 2));

    Output:

    {
      "A": 1,
      "B": 2,
      "C": [
        "D"
      ]
    }

    When you deal with non-primitives (in Monkey C's case, Array and Dictionary), an assignment results in grabbing a reference to the non-primitive's value, not a copy of its value.

    In your case, the "unexpected" behavior is because Array is a reference type (or "container type", as the Monkey C documentation puts it.) It would've been same even without the use of a Dictionary.

    e.g.

    var x = [];
    var y = x;
    x.add("D");

    // x and y both refer to the same array, so the expressions x[0] and y[0] will both evaluate to "D".

    All of that is to say, of all the valid criticisms of Monkey C, this really isn't one of them (IMO). (Except perhaps it could be better documented?)

  • @as you see, not only me have different look on case, but rules are rules

  • @as you see, not only me have different look on case, but rules are rules

    Sure, but my point is that Monkey C didn't make up some crazy and outrageous behavior that nobody has ever seen before. Anyone who's used JavaScript or Python will be very familiar with how this works (see the js example I posted above - it works exactly like the OP's example).

    I've also used lots of other languages (C, C++, Java, C#, etc.) and the js/python/monkey c way of doing things doesn't throw me off.

    If you've never written JavaScript or Python, I could understand how this could throw you off.

    Like I said, maybe it could've been better documented, and maybe there could've been some examples.

  • Yes, you are right, I've never written in JavaScript or Python. Fortran, pascal, c, c++  these times Slight smile

  • Yes, you are right, I've never written in JavaScript or Python. Fortran, pascal, c, c++  these times

    Makes sense. From a C POV, imagine that you are not allowed to nest structures and arrays inside other structures and arrays, but you always have to use *pointers* to structs and arrays everywhere. That's how modern scripting languages like js and python work: you always get a reference to a complex object, as opposed to a copy. You just have to know the difference between primitive / value types and complex / reference types.

    You might want to try out python and js just for fun. It's helpful these days to know at least one of those two languages, as they're pretty popular and widespread. With js, you can play around with it in your browser, so that's a bonus. You'll see in the Garmin Connect (web app) forums that a few ppl provided some js scripts for enhancing Garmin Connect's functionality.

    Also, when I quoted your emoji and tried to post my comment, I got a forum error which implied I tried to upload an unknown file. There's really no end to the ridiculous bugs in this platform...

  • However, when I modify the variable 'myarray', It's modifying the dictionary as well, and it's driving me crazy

    Just for the benefit of anyone else skimming this thread: in Monkey C (and other languages like JavaScript and Python), the correct way of looking at this is that the original dictionary was never actually modified.

    The dictionary has a reference to the array (associated with the key "C"), so in the line which initializes myarray, you're getting a reference to the same array's contents, not a copy of its contents.

    I ended up just creating a new blank array and using .addAll to fill the new array with the old contents

    Another way to do this would be to use Array.slice(). e.g.

    var myarray = storagedict.get("C").slice(null, null); // get copy of array