Reputation: 26356
Is there a safe way to mutate the value of a tdictionary, while iterating?
The first naive try:
var p: tpair<keytype,valuetype>;
begin
for p in coll do
// p.value is readonly for valuetypes and their fields.
end;
failed, and also wrapping the valuetype in a RECORD doesn't help.
Iterating over keys and using dosetvalue might work, but it is private only.
I could of course use a reference type, but that seems a bit silly to me, since the state is an integer. Not elegant.
Added, complete sample:
program gendicttest;
// tests if you can set valuetype key.
{$APPTYPE CONSOLE}
uses
generics.collections;
type
TCycleList = tdictionary<integer,integer>; // the value a record type doesn't work either.
var cyclelist :TCycleList;
p : tpair<integer,integer>;
j:integer;
begin
cyclelist:=tcyclelist.Create;
cyclelist.Add(3,4);
for p in cyclelist do
writeln(p.Key, ' ',p.Value);
if cyclelist.TryGetValue(3,j) then
cyclelist.AddOrSetValue(3,j+1);
for p in cyclelist do
p.Value:=0; // <-- here, and alternative to do this.r
for p in cyclelist do
writeln(p.Key, ' ',p.Value);
end.
Upvotes: 0
Views: 208
Reputation: 28806
Of course it won't work! The pair returned is a copy. So you can at best modify the copy, which makes no sense.
If you only want to clear the values, then get a copy of the keys and enumerate over them to set the value of each key to 0.
for var I in cycleList.Keys do
cycleList.AddOrSetValue(I, 0);
Alternatively, you can use Items, which can be indexed with a key:
for var I in cycleList.Keys do
cycleList.Items[I] := 0;
note: can also be done without Rio syntax
Upvotes: 1