【问题标题】:How to iterate a TDictionary and delete item?如何迭代 TDictionary 并删除项目?
【发布时间】:2013-10-28 04:30:21
【问题描述】:

我有一个 TDictionary 并向其中添加了一些项目:

for index := 0 to 10 do
   dict.Add(IntToStr(index), index);

现在,我需要迭代容器并删除我想要的项目:

pairEnum := dict.GetEnumerator;
while pairEnum.MoveNext do
begin
  if pairEnum.Current.Value mod 2 = 0 then
     dict.Remove(pairEunm.Current.Key);
end;

我希望我现在字典中只有奇数。但我实际得到的是:

key=1 value=1
key=3 value=3
key=5 value=5
key=7 value=7
key=9 value=9
key=8 value=8 <-

为什么“8”没有从字典中删除?

如果我添加更多项目。例如

for index := 0 to 12 do
   dict.Add(IntToStr(index), index);

那么,结果是正确的。这是为什么?如何正确迭代 TDictionary 并删除项目?谢谢。

【问题讨论】:

    标签: delphi-xe2


    【解决方案1】:

    在迭代枚举时删除项目是不安全的。您应该保留另一个要删除的键列表,并在迭代完成后开始删除它们。

    【讨论】:

      【解决方案2】:

      您需要反向遍历字典。不幸的是,默认情况下,Delphi 不提供“For MyObj in dict Reverse”或类似功能,因此您必须以另一种方式执行此操作:

      for ix := dict.Count - 1 downto 0 do
        if (dict.Keys.ToArray[ix] mod 2) = 0 then
          dict.Remove(dict.Keys.ToArray[ix]);
      

      【讨论】:

        【解决方案3】:

        迭代中的以下迭代和删除形式似乎有效。

        var
          Item: TPair<string, integer>;
        
        for Item in dict do
        begin
          if Item.Value mod 2 = 0 then
            dict.Remove(Item.Key);
        end;
        

        这可能工作正常,因为键和值被清空,但位置实际上并没有被删除,并且迭代不会丢失它所在的位置并且可以继续。

        【讨论】:

        • 我在 TDictionary 上进行了 TPair 迭代,并且在其中执行 .Remove 时处理了 10 个项目中的 8 个。所以idursun's statement 似乎仍然正确。
        • 是的@MA-Maddin,你是对的。我的答案是错误的。你必须像 SteveC 所说的那样通过反向迭代来做到这一点。
        猜你喜欢
        • 1970-01-01
        • 2022-11-17
        • 1970-01-01
        • 2016-04-25
        • 1970-01-01
        • 1970-01-01
        • 2014-09-08
        • 1970-01-01
        • 2022-05-17
        相关资源
        最近更新 更多