www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Accessing contents of associative arrays in an optimal way

reply phant0m <asoeifjasoi sioudfhjsiuodhf.com> writes:
Suppose I have AA of structures:

struct Foo {
     int value;
     string name;
}

Foo[int] records;

As far as I know, AA implemented as a hashtable. So, will there 
be two searches performed (one search for each line)?
records[3].value = 10;
records[3].name = "name";

How can I access elements of this AA by a "reference"? In C++ I 
can use reference to an element of the map:
Foo& foo = records.find(3).second;
foo.value = 10;
foo.name = "name";

I found that in D I can use a "with" keyword to achieve the same 
effect:
with(values[0]) {
     value = 10;
     name = "name";
}

Is this the only optimal way?
Jul 09 2016
next sibling parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 07/09/2016 01:32 PM, phant0m wrote:
 Suppose I have AA of structures:

 struct Foo {
      int value;
      string name;
 }

 Foo[int] records;

 As far as I know, AA implemented as a hashtable. So, will there be two
 searches performed (one search for each line)?
 records[3].value = 10;
 records[3].name = "name";
Yes, two searches. Although it is slower, it's still O(1). :)
 How can I access elements of this AA by a "reference"?
The 'in' operator returns a pointer to the element: import std.stdio; struct Foo { int value; string name; } void main() { Foo[int] records; records[3] = Foo(42, "hello"); if (auto record = 3 in records) { record.value = 10; record.name = "name"; } writeln(records); } Ali
Jul 09 2016
prev sibling next sibling parent ag0aep6g <anonymous example.com> writes:
On 07/09/2016 10:32 PM, phant0m wrote:
 As far as I know, AA implemented as a hashtable. So, will there be two
 searches performed (one search for each line)?
 records[3].value = 10;
 records[3].name = "name";
Yup. A good optimizer may be able to eliminate one, but conceptually there are two lookups.
 How can I access elements of this AA by a "reference"? In C++ I can use
 reference to an element of the map:
 Foo& foo = records.find(3).second;
 foo.value = 10;
 foo.name = "name";
You can take the address of `records[3]`: ---- Foo* foo = &records[3]; foo.value = 10; foo.name = "name"; ---- If `records[3]` may be not set, you can use `3 in records` to get a pointer to the value or null if the key isn't set: ---- Foo* foo = 3 in records; if (foo is null) {records[0] = Foo.init; foo = 3 in records;} foo.value = 10; foo.name = "name"; ----
Jul 09 2016
prev sibling parent phant0m <asoeifjasoi sioudfhjsiuodhf.com> writes:
Thank you!
Jul 09 2016