d

Iterate over key/value pairs in associative array in D.


I don't know why I cannot find an answer to this on the web. It seems such a simple thing.

The associative array has a byValue member and a byKey member for iterating over the values and the keys. There's also a byKeyValue member for iterating over key/value pairs. It's just not clear what type it returns for iterating using foreach, and the compiler complains that auto is not good enough here.

The language docs (https://dlang.org/spec/hash-map.html) call it an "opaque type".

Any idea how to get the commented code working? Thank you!

int main(){
  int[string] contained;

  contained["foo"] = 4;
  contained["bar"] = 5;
  contained["gooey"] = 7;

  writeln("*by values*");
  foreach(int i ; contained.byValue){
    writeln(i);
  }

  writeln("*by keys*");
  foreach(string i ; contained.byKey){
    writeln(i);
  }

  // writeln("*by key/values*");
  //foreach(auto i ; contained.byKeyValue){
  //writeln(i.key,i.value);
  //}

  return 0;
}

Solution

  • So first, you don't even strictly need a thing:

    foreach(key, value; contained) {
       // use right here
    }
    

    But the .byKeyValue thing can be more efficient, so it is cool to use... just don't specify a type at all (in fact, you very rarely have to with D's foreach, and btw it is always wrong to use auto in the foreach statement - a common mistake since it is used in many other places...)

    foreach(item; contained.byKeyValue()) {
       writeln(item.key, " ", item.value);
    }
    

    Also btw you can use void main if you always want main to return 0 - the language will do that automatically.