Principled method of lookup-or-insert in associative arrays?
Tomek Sowiński
just at ask.me
Sat Nov 20 06:45:58 PST 2010
Andrei Alexandrescu <SeeWebsiteForEmail at erdani.org> napisał(a):
> 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?
To be honest I find the 2nd snippet more readable, it's just one line more:
uint[string] map;
foreach (line; stdin.byLine()) {
if (auto p = line in map) ++*p;
else map[line.idup] = 1;
}
You know exactly what it does and it's const correct. I don't see value in
implicit cloning.
The first example smells of STL map[key] -- if key is not found, it
implicitly inserts key, initializes the value, and returns a reference.
Let's not go there.
--
Tomek
More information about the Digitalmars-d
mailing list