John Pretz
John Pretz

Reputation: 43

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;
}

Upvotes: 4

Views: 980

Answers (2)

chikega
chikega

Reputation: 155

This is just to provide a complete working example for those that are learning D, like myself:

module assoc_array;

import std.stdio;  

void main() {

    int[string] contained;

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

    writeln("By Values: ");
    foreach (value ; contained.byValue) {
        writeln(value);
    }

    writeln("By Keys: ");
    foreach (key ; contained.byKey) {
        writeln(key);
    }

    writeln("By Key/Values: ");
    foreach (pair ; contained.byKeyValue) {
        writeln(pair.key, ": ", pair.value);
    }
}

Also here's alternate syntax to initialize the associative array fields:

   int[string]contained = [
                      "foo"   : 4,  
                      "bar"   : 5,
                      "gooey" : 15 ];

Upvotes: 0

Adam D. Ruppe
Adam D. Ruppe

Reputation: 25605

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.

Upvotes: 8

Related Questions