Librerías: CDictionary

 

CDictionary:

Implementación del diccionario (array asociativo) en MQL5 a base de CArrayObj y CList.

Autor: Enrico Lambino

 
Automated-Trading:

Clase CDictionary:

Autor: Enrico Lambino

Hola Enrico,

Muy buen trabajo compañero.

Gracias,

Shep

 
Shephard Mukachi:

Hola Enrico,

Muy buen trabajo compañero.

Gracias,

Shep

De nada. Lo subí como prometí :)

Además, tenías mucha razón en lo de la serialización. Pasé por alto el método CreateElement() en CArrayObj. Sólo es posible guardar y cargar objetos si sabes de antemano qué tipo de objetos guardar y cargar, o si MQ introduce una nueva característica que convierte string a tipo genérico. Es por eso que lo subí sin los métodos Save() y Load() en él.

 

Una aplicación muy inteligente. Buen trabajo. He hecho algunos cambios para que sea más fácil trabajar con él (para mis necesidades). En lugar de contener múltiples tipos de datos, esta versión modificada sólo contiene uno, pero no requiere especificar el tipo de datos cuando se llama al método get, y tampoco requiere una entrada de clave de cadena, ya que la clave se modela y se convierte en cadena dentro de la clase diccionario. Ejemplo:


   CDictionary<double> dict;
   for(int i=0;i<Bars;i++)
      dict.Add(Time[i],Close[i]);
   for(int i=0;i<Bars;i++)
      if(dict[Time[i]] != Close[i])
         Print("Collision Error ",++cnt); 
Archivos adjuntos:
Dictionary.mqh  16 kb
 
nicholishen:

Una aplicación muy inteligente. Buen trabajo. He hecho algunos cambios para que sea más fácil trabajar con él (para mis necesidades). En lugar de contener múltiples tipos de datos, esta versión modificada sólo contiene uno, pero no requiere especificar el tipo de datos cuando se llama al método get, y tampoco requiere una entrada de clave de cadena, ya que la clave se modela y se convierte en cadena dentro de la clase diccionario. Ejemplo:


Interesante versión. Gracias por compartir tus ideas.

Las versiones anteriores de esta clase tiene Dictionary<T> en ella. Pero más tarde lo cambié. Para mis propias necesidades, necesitaba algo donde pudiera almacenar varios tipos de datos a la vez, pero también puedo ver algunas aplicaciones donde tu versión es más adecuada para la tarea (y menos engorrosa, estoy de acuerdo).

 

Como complemento, utilizo la clase del mismo nombre de @Vasiliy Sokolov, funciona de maravilla. Acabo de ver este, vamos a descargarlo ahora

https://www.mql5.com/es/articles/1334

Рецепты MQL5 - Реализуем ассоциативный массив или словарь для быстрого доступа к данным
Рецепты MQL5 - Реализуем ассоциативный массив или словарь для быстрого доступа к данным
  • 2015.03.23
  • Vasiliy Sokolov
  • www.mql5.com
Эта статья описывает удобный класс для хранения информации - ассоциативный массив или словарь. Благодаря этому классу можно получать доступ к информации по ее ключу. Ассоциативный массив напоминает обычный массив, однако вместо индекса он использует некий уникальный ключ, например, перечисление ENUM_TIMEFRAMES или какой-либо текст. Что...
 

Muy buen trabajo.

Para mí, simplemente no entiendo el beneficio de extender CArrayObj, ya que la mayoría de las cosas que hacer con CArrayObj están prohibidas en CDictionary (como Sort() etc.) y puede estropear en caso de mal uso.
En realidad, CDictionary no es un CArrayObj (desafía el principio de liskov de la herencia). Así que no hay un uso real del CArrayObj.
Yo extendería CObject en su lugar y tendría m_data[] dentro en su lugar.

*-Nueva versión de DictionarySingle: Añadida iteración en serie y gestión de memoria, algunas refactorizaciones menores.
Archivos adjuntos:
 
Amir Yacoby:

Muy buen trabajo.

Para mí, simplemente no entiendo el beneficio de extender CArrayObj, ya que la mayoría de las cosas que hacer con CArrayObj están prohibidas en CDictionary (como Sort() etc.) y puede estropear en caso de mal uso.
En realidad, CDictionary no es un CArrayObj (desafía el principio de liskov de la herencia). Así que no hay ningún uso real de la CArrayObj.
Yo extendería CObject en su lugar y tendría m_data[] dentro en su lugar.

Supongo que es porque MQL no permite

class SubClass : private SuperClass


Pero no hay necesidad de tirar el bebé con el agua del baño. Usted podría simplemente envolver un objeto CArrayObj en lugar de implementar a través de la derivación.
 
nicholishen:

Supongo que es porque MQL no permite

class SubClass : private SuperClass


Pero no hay necesidad de tirar el bebé con el agua del baño. Usted podría simplemente envolver un objeto CArrayObj en lugar de implementar a través de la derivación.

Envolver fue mi primera opción.
Pero luego me di cuenta de que no es tan trivial, como el m_data_max y m_data_total ambos protegidos en CArrayObj y sólo tienen un getter, y el algoritmo necesita un setter.
El m_data_max también se utiliza un poco diferente en CArrayObj.

Pero de todos modos,

class SubClass : private SuperClass

está permitido en MQL5, lo cual puede ser una solución.
La única razón que veo para usar CArrayObj es por liberar memoria, lo cual es bastante simple de hacer.
Porque no veo que se use nada más de CArrayObj.

Se usa mayormente como CObject *m_data[] - y esa no es una razón suficiente para extenderlo en mi opinión.

 
Amir Yacoby:

Wrapping fue mi primera opción.
Pero luego me di cuenta de que no es tan trivial, ya que el m_data_max y m_data_total ambos protegidos en CArrayObj y sólo tienen un getter, y el algoritmo necesita un setter.
El m_data_max también se utiliza un poco diferente en CArrayObj.

Pero de todos modos,

está permitido en MQL5, lo cual puede ser una solución.
La única razón que veo para usar CArrayObj es por liberar memoria, lo cual es bastante simple de hacer.
Porque no veo que se use nada más de CArrayObj.

Se usa mayormente como CObject *m_data[] - y esa no es una razón suficiente para extenderlo en mi opinión.

Agradezco tus aportaciones. Estoy de acuerdo. Usar CArrayObj es algo opcional en este caso.
Hay muchas alternativas. Puedes hacer que la superclase sea privada como has dicho, o heredar directamente de CObject (tu código de ejemplo), o encontrarte a medio camino: extender CArray en lugar de CArrayObj para que esté a salvo de un mal uso accidental (no se hace ordenación real).
La mayoría de los métodos necesarios de CArrayObj no son tan difíciles de reimplementar. La mia es una solucion de opinion (he optado por reutilizar todo el codigo que he podido para esta clase).
Siéntase libre de modificar como mejor le parezca.

 
versión actualizada de DictionarySingle - añadida iteración en serie en el orden de adición de objetos, añadida autogestión de memoria y una pequeña refactorización.
Ejemplo para iteración:
   CDictionary<double> dict;
    datetime time[];
   double close[];
   ulong bars=Bars(_Symbol,_Period);
   ArraySetAsSeries(time,true);
   ArraySetAsSeries(close,true);
   CopyTime(_Symbol,_Period,0,Bars(_Symbol,_Period),time);
   CopyClose(_Symbol,_Period,0,Bars(_Symbol,_Period),close);
   for(int i=0;i<20;i++) //Bars(_Symbol,_Period);i++)
     {
      dict.Add(time[i],close[i]);
      //dict.Add(time[i],close[i]*100);
     }

   //--- adelante
   CDictionaryEntry<string> *node=dict.GetFirstNode();
   for(int i=0; node!=NULL; i++)
     {
      printf((string)i+":\t"+node.Value());
      node=dict.GetNextNode();
     }
   //--- hacia atrás
   node=dict.GetLastNode();
   for(int i=0; node!=NULL; i++)
     {
      printf((string)i+":\t"+node.Value());
      node=dict.GetPrevNode();
     }
Archivos adjuntos: