arraysdictionaryassociative-arrayd

Dlang associative array of an array of strings keyed by a string has unexpected behavior


The output from the following code does not behave how I think it should. It appears that making changes to the string array returned by testAA.require() does not reflect in the associative array. I thought dynamic arrays were pass by reference, but this seems to be behaving contrary to this notion. Re-assigning the array to testAA does appear to work, but the reason why this does not work is bothering me. Any tips or ideas would be appreciated!

module main;

import std.stdio;

void main()
{
  string[][string] testAA;
  string[] vals = ["InitVal1", "InitVal2"];

  auto list = testAA.require("Key", vals);

  writeln("list: ", list);

  list ~= "Val1";
  list ~= "Val2";

  writeln("list: ", list);
  writeln("testAA", testAA);
}

This results in the output:

list: ["InitVal1", "InitVal2"]
list: ["InitVal1", "InitVal2", "Val1", "Val2"]
testAA["Key":["InitVal1", "InitVal2"]]

Solution

  • The call to update isn't necessary after the require, just do testAA["Key"] ~= "Val1". Note that this does not update list, which is again, still a copy of the array slice at the time it was added.

    If you want to do it by reference, you need to use a pointer:

    auto list = &testAA.require("Key", vals); // keep a pointer to the array
    *list ~= "Val1";
    *list ~= "Val2";
    

    If I'm unsure if an AA has a key, I usually will do aa.require(key) ~= val;. This is a bit less nice than just indexing, but basically equivalent to indexing, putting in a value.init when it doesn't yet exist.