Principled method of lookup-or-insert in associative arrays?

Bruno Medeiros brunodomedeiros+spam at com.gmail
Thu Dec 2 06:23:50 PST 2010


On 02/12/2010 14:18, Bruno Medeiros wrote:
> On 20/11/2010 08:07, Andrei Alexandrescu wrote:
>> TDPL has an example that can be reduced as follows:
>>
>> void main() {
>> uint[string] map;
>> foreach (line; stdin.byLine()) {
>> ++map[line];
>> }
>> }
>>
>> byLine reuses its buffer so it exposes it as char[]. Therefore,
>> attempting to use map[line] will fail. The program compiled and did the
>> wrong thing because of a bug.
>>
>> The challenge is devising a means to make the program compile and work
>> as expected. Looking up an uint[string] with a char[] should work, and
>> if the char[] is to be inserted, a copy should be made (via .idup or
>> to!string). The rule needs to be well defined and reasonably general.
>>
>> The effect is something like this:
>>
>> void main() {
>> uint[string] map;
>> foreach (line; stdin.byLine()) {
>> auto p = line in map;
>> if (p) ++*p;
>> else map[line.idup] = 1;
>> }
>> }
>>
>> Ideally the programmer would write the simple code (first snippet) and
>> achieve the semantics of the more complex code (second snippet). Any
>> ideas?
>>
>> Andrei
>
> An idea:
>
> import std.conv;
> //...
> uint[string] map;
> foreach (line; stdin.byLine()) {
> map.getOrPut(line, 0, to!string) ++;
> }
>
>

Also, it doesn't use pointers, which I guess may be a bit of an advantage.

-- 
Bruno Medeiros - Software Engineer


More information about the Digitalmars-d mailing list