- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 Delphi Berlin 10.1(最新更新),并且我的应用程序中的 TDictionary 遇到一些特定值的问题。 “for..in”无法正确循环。
下面是一个示例代码,其中“for...in”不循环遍历所有值,另一个示例则循环遍历所有值。
在第一种情况下,“for...in”循环仅执行两个步骤,而在第二种情况下,它会执行所有步骤。
procedure TForm1.btn1Click(Sender: TObject);
var
tmpPar: TPair<Integer, Integer>;
tmpDictionary: TDictionary<Integer, Integer>;
begin
// NOT WORKING
tmpDictionary := TDictionary<Integer, Integer>.Create;
try
tmpDictionary.Add(631, 40832);
tmpDictionary.Add(1312, 40837);
tmpDictionary.Add(5947, 40842);
for tmpPar in tmpDictionary do
begin
tmpDictionary.Remove(tmpPar.Key);
end;
finally
tmpDictionary.Free;
end;
// WORKING
tmpDictionary := TDictionary<Integer, Integer>.Create;
try
tmpDictionary.Add(123, 5432);
tmpDictionary.Add(453, 23);
tmpDictionary.Add(76, 2334);
for tmpPar in tmpDictionary do
begin
tmpDictionary.Remove(tmpPar.Key);
end;
finally
tmpDictionary.Free;
end;
end;
第一种情况有问题吗?
提前致谢!
最佳答案
你的例子只是运气好而已 - 不应该期望这个构造会表现良好。如果您单步执行示例,您会发现第一种情况在删除时调用列表重新排序,但第二个示例则不会。
要了解发生了什么,请检查从字典中删除项目的代码:
function TDictionary<TKey,TValue>.DoRemove(const Key: TKey; HashCode: Integer;
Notification: TCollectionNotification): TValue;
var
gap, index, hc, bucket: Integer;
LKey: TKey;
begin
index := GetBucketIndex(Key, HashCode);
if index < 0 then
Exit(Default(TValue));
// Removing item from linear probe hash table is moderately
// tricky. We need to fill in gaps, which will involve moving items
// which may not even hash to the same location.
// Knuth covers it well enough in Vol III. 6.4.; but beware, Algorithm R
// (2nd ed) has a bug: step R4 should go to step R1, not R2 (already errata'd).
// My version does linear probing forward, not backward, however.
// gap refers to the hole that needs filling-in by shifting items down.
// index searches for items that have been probed out of their slot,
// but being careful not to move items if their bucket is between
// our gap and our index (so that they'd be moved before their bucket).
// We move the item at index into the gap, whereupon the new gap is
// at the index. If the index hits a hole, then we're done.
// If our load factor was exactly 1, we'll need to hit this hole
// in order to terminate. Shouldn't normally be necessary, though.
{... etc ...}
您会看到,实现了一种算法,该算法决定在删除项目时何时以及如何对基础列表进行重新排序(这是为了尝试优化已分配内存块中间隙的位置以优化将来的插入)。枚举只是在基础列表中的索引中移动,因此一旦您从列表中删除一个项目,枚举器就不再有效,因为它只会将您移动到基础列表中的下一个索引,该索引已更改。
对于普通列表,删除时通常会反向迭代。但是,对于字典,您必须首先构建要在第一次枚举过程中删除的键列表,然后枚举该列表以将它们从字典中删除。
关于delphi - 使用 TDictionary "for...in",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46797980/
将 TDictionary 分配给 TObject 变量。我可以在同一项目中将 TOBject 转换回 TDictionary。但是,如果在引用的 bpl 项目中完成转换,则转换会失败,具体取决于项目
我有一本 TDictionary。它充满了一个广泛的循环。当循环结束时,我需要检索 10 个键(字符串)和更多分数(整数)。实现这一目标最有效的方法是什么? 在 Objective-C(Cocoa)
有人有TDictionary的示例代码吗?在其构造函数期间填充? 最佳答案 显然你只是想要一句台词,所以我尝试了一下,实现了 TDictHelper允许使用单行代码创建和填充字典。 使用任何形式的单行
我有很多文件(大约 160 000 个),我需要有关文件中各个单词的位置的信息(全文)。所以我像这样使用字典: WordDict : TDictionary>; 现在我知道 WORD1 位于 FILE
我正在使用 Delphi Berlin 10.1(最新更新),并且我的应用程序中的 TDictionary 遇到一些特定值的问题。 “for..in”无法正确循环。 下面是一个示例代码,其中“for.
有没有更聪明的方法(用更少的代码)从 TDictionary 中获取所有键作为单个字符串,逗号分隔 var FDicList : TDictionary ; KeyStrList: TStri
我正在尝试将以下值添加到 procedure TForm1.FormCreate(Sender: TObject); var md: TDictionary; s, v: string; be
我使用 TDictionary 来处理大量数据。如何检测大小增加 TDictionary 的时刻? 最佳答案 如果您希望检测底层私有(private)存储何时增长,那么您不能。这由私有(private
我需要在 Delphi (XE) 中自定义编码/取消编码 TDictionary。字典声明为: TMyRecord = record key11: integer; key12: string
我刚刚考虑使用新的 TDictionary 类型。但在 QualityCentral 上,我读到了两起由 TDictionary 引起的内存泄漏: http://qc.codegear.com/wc/
我对通用集合没有经验。我需要对 TDictionary 进行排序。 type TSearchResult = TPair; var target_results : TDictionary;
已关闭。这个问题是 off-topic 。目前不接受答案。 想要改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 已关闭14 年前。 Improve th
我想做这样的事情,但它不会编译,因为无法分配 Pair。 var MyDictionary: TDictionary; Pair: TPair; begin // ... create a
我有一个类似的 TDictionary target_results : TDictionary; 填充后我需要对结果进行排序。我就是这样做的 type TSearchResult = TPair
我想在 Delphi 项目中使用 TDictionary。但我有一个问题,如何按默认值创建 TDictionary 常量数组? 例如,我想为字典分配 4 个项目,例如下面的代码(对于 TItem 的常
这重现了问题: program Project1; {$APPTYPE CONSOLE} uses Generics.Collections; type TStringRec = record
我尝试使用标准delphi序列化器序列化/反序列化标准delphi容器。 procedure TForm7.TestButtonClick(Sender: TObject); var dict
我已经定义了一个从 TDictionary 派生的集合,并且需要定义一个应用附加过滤器的自定义枚举器。 我陷入困境,因为我无法访问 TDictionary FItems 数组(它是私有(private
是否有一种方法或简单的方法可以将一个 TDictionary 内容复制到另一个 TDictionary 内容中?假设我有以下声明 type TItemKey = record ItemID
可以使用记录作为 TDictionary 中的键值吗?我想根据字符串、整数和整数的组合来查找对象。 TUserParKey=record App:string; ID:integer; N
我是一名优秀的程序员,十分优秀!