digitalmars.D.learn - Accessing contents of associative arrays in an optimal way
- phant0m (22/22) Jul 09 2016 Suppose I have AA of structures:
- =?UTF-8?Q?Ali_=c3=87ehreli?= (18/29) Jul 09 2016 The 'in' operator returns a pointer to the element:
- ag0aep6g (17/26) Jul 09 2016 Yup. A good optimizer may be able to eliminate one, but conceptually
- phant0m (1/1) Jul 09 2016 Thank you!
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
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
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