文章 "MQL5秘笈之:采用关联数组或字典实现快速数据访问" - 页 4

 
Vasiliy Sokolov:

这可能有几个原因。最有可能的是类型不兼容或指针处理不当。此外,我们也不能排除使用模板方法的特殊性(其中也有自己的细微差别)。

一般来说,最好使用现成的交易引擎,这样可以节省大量时间和精力:https://www.mql5.com/zh/articles/2166。

下午好!您能告诉我如何在整个字典中循环,根据特定条件删除交易对吗?下面是这样一个例子。

#include <Dictionary.mqh>

class CInt : public CObject
  {
public:
   int               value;
                     CInt(int _value = 0) : value(_value) {}
  };
  
CDictionary d;
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
int OnInit()
  {
   d.FreeMode(true);
   for(int i = 0; i < 10; ++i)
     {
      CInt *int_value = new CInt(i);
      d.AddObject(i, int_value);
     }
   for(CInt *node = d.GetFirstNode(); node != NULL;)
     {
      if(node.value % 2 == 0)
         // d.DeleteCurrentNode() 或 d.DeleteObjectByKey(node.value);
         
      // 如何遍历字典???? 
     }
     
   return(INIT_SUCCEEDED);
  }
 
vek_y4icb:

下午好!您能告诉我如何在整个字典中循环,根据特定条件删除字对吗?下面是这样一个例子。

问得好。现在我检查了使用您的方法进行删除的情况--效果不佳。我会研究一下的。

 
Vasiliy Sokolov:

问得好。我现在用你的方法检查了删除情况--没有正常工作。我会研究一下。

在一般情况下,它不应该正常工作。

从关联数组中执行多次删除的正确方法是收集要删除的键的数组,然后按键删除。

 
Andrei Trukhanovich:

在一般情况下,它不必正确工作。

从关联数组中执行多次删除的正确方法是收集要删除的键的数组,然后按键删除。

这是可以理解的,但同样也是不必要的工作。

 
Vasiliy Sokolov:

问得好。我现在用你的方法检查了删除情况--没有正常工作。我会研究一下。

感谢您的回复!

 
Andrei Trukhanovich:

一般情况下不一定要正确工作。

从关联数组中执行多次删除的正确方法是收集要删除的键的数组,然后按键删除。

问题就在这里,即使是这种方法也会突然出现一个奇怪的错误。这显然是个错误。我会研究一下。

目前,我建议你创建一个新的字典,并将不需要删除的值添加到其中。然后清除旧字典。这将 100% 有效。

 

开始吧:

1. 将字典版本更新为本帖子所附的版本。

2.运行测试脚本删除偶数元素。

删除应分两次完成:

int OnStart()
  {
   d.FreeMode(true);
   for(int i = 0; i < 10; ++i)
   {
      CInt *int_value = new CInt(i);
      d.AddObject(i, int_value);
   }
   //-- 创建要删除的键的列表
   CArrayInt delKeys;
   for(CInt *node = d.GetFirstNode(); node != NULL; node = d.GetNextNode())
   {
      if(node.value % 2 == 0)
         delKeys.Add(node.value);
   }
   //-- 逐个删除指定要删除的对象。
   for(int i = 0; i < delKeys.Total(); i++)
      d.DeleteObjectByKey(delKeys.At(i));
   for(CInt *node = d.GetFirstNode(); node != NULL; node = d.GetNextNode())
   {
      printf(node.value);
   }
     
   return(INIT_SUCCEEDED);
  }

关于DeleteCurrentObject() 方法:

该方法只能与 ContainsKey() 函数结合使用。将其作为公共方法的唯一原因是,在这种情况下,调用该方法可以节省重新定位指针的时间。也就是说,其典型且唯一的使用情况是:1.检查是否存在键,2. 如果存在,则使用该方法快速删除。

附加的文件:
 
vek_y4icb:

这是可以理解的,但同样也是不必要的车身装饰。

从技术上讲,可以按照您的期望进行一次拆卸。但会很复杂。这就是为什么现在还不行,只能分两次进行。从字典作为分布式数据结构 的角度来看,两次删除是一种更正确的解决方案。只是在用户层面上,删除似乎是按顺序进行的,而实际上一切都不同。就性能而言,单程删除不会带来任何好处。就方便性而言,是的,它可能更方便。

 
Vasiliy Sokolov:

从技术上讲,可以按照你的期望进行一次清除。但会很复杂。这就是为什么现在还不能进行两次删除的原因。从字典作为分布式数据结构 的角度来看,两次删除更符合规范。只是在用户层面上,删除似乎是按顺序进行的,而实际上一切都不同。就性能而言,单程删除不会带来任何好处。就方便性而言,是的,它可能更方便。

谢谢。

 
Marcel Fitzner:

我想我在删除一个元素并试图进入最后一个元素时发现了一个错误:

CDictionary.mqh 中会出现错误:

Dictionary.mqh 中的无效指针 访问 (463,9)

有人能确认这一点吗?有任何修复方法吗?



这是在第 500 && 501 行检查指针时出现的错误。

使用内置的 CheckPointer() 进行了修复。

附加的文件:
CDictionary.mqh  21 kb