ライブラリ: CDictionary

 

CDictionary:

CArrayObjとCListに基づくMQL5ライブラリ(連想配列)データ構造の実装です。

作者: Enrico Lambino

 

こんにちは、エンリコ、

とてもいい仕事だ。

ありがとう、

シェップ

 
Shephard Mukachi:

こんにちは、エンリコ、

とても素晴らしい仕事だ。

ありがとう、

シェップ

どういたしまして。約束通りアップロードしたよ :)

また、シリアライズの部分については、あなたの言う通りでした。CArrayObjの CreateElement()メソッドを見落としていました。 オブジェクトのセーブとロードができるのは、セーブとロードするオブジェクトの型をあらかじめ知っているか、MQが文字列をジェネリック型に変換する新機能を導入した場合だけです。そのため、Save()メソッドとLoad()メソッドを入れずにアップロードした。

 

非常に巧妙な実装。いい仕事だ!私はこれを(私のニーズに合わせて)使いやすくするために、いくつか手を加えてみた。複数のデータ型を保持する代わりに、この微調整されたバージョンは1つしか保持しませんが、getメソッドを呼び出すときにデータ型を指定する必要はありません。また、キーはテンプレート化され、辞書クラス内で文字列にキャストされるので、文字列キーの入力も必要ありません。例


   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); 
ファイル:
Dictionary.mqh  16 kb
 
nicholishen:

非常に巧妙な実装。いい仕事だ!私はこれを(私のニーズに合わせて)使いやすくするために、いくつか手を加えてみた。複数のデータ型を保持する代わりに、この微調整されたバージョンは1つしか保持しませんが、getメソッドを呼び出す際にデータ型を指定する必要はありません。また、キーはテンプレート化され、辞書クラス内で文字列にキャストされるので、文字列キーの入力も必要ありません。例


興味深いバージョンですね。アイデアを教えてくれてありがとう。

このクラスの以前のバージョンでは、Dictionary<T>がありました。しかし、後で変更しました。私自身のニーズとしては、様々なタイプのデータを同時に格納できるものが必要でしたが、あなたのバージョンの方がタスクに適している(そして、より面倒でない、私もそう思います)アプリケーションもあります。

 

補足として、私は@Vasiliy Sokolovの同名のクラスを使っています。ちょうどこれを見たところだったので、今ダウンロードしてみよう。

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

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

とても素晴らしい仕事だ。

私にとっては、CArrayObjを 拡張する利点が理解できません。CArrayObjで行うほとんどのことは、CDictionaryでは禁止されており(Sort()など)、悪用された場合に混乱する可能性があるからです。
実際、CDictionaryはCArrayObjではありません(継承のリスコフの原則に反しています)。そのため、CArrayObjの本当の使い道はありません。
私なら、代わりにCObjectを拡張し、その中にm_data[]を入れます。

*-DictionarySingleの新バージョン:シリアルイテレーションとメモリ管理を追加し、若干のリファクタリングを行った。
ファイル:
 
Amir Yacoby:

とても素晴らしい仕事だ。

私にとっては、CArrayObjを拡張する利点が理解できません。CArrayObjで行うほとんどのことは、CDictionaryでは禁止されており(Sort()など)、悪用された場合に混乱する可能性があるからです。
実際、CDictionaryはCArrayObjではありません(継承のリスコフの原則に反しています)。そのため、CArrayObjの本当の使い道はありません。
私なら代わりにCObjectを拡張し、その中にm_data[]を入れます。

これはMQLでは

class SubClass : private SuperClass


しかし、赤ん坊を風呂の水と一緒に捨てる必要はありません。派生によって実装する代わりに、CArrayObjオブジェクトを 単純にラップすることができます。
 
nicholishen:

それは、MQLが以下を許可していないからだと思う。

class SubClass : private SuperClass


しかし、赤ん坊を風呂の水と一緒に捨てる必要はありません。派生によって実装する代わりに、CArrayObjオブジェクトを単純にラップすることができます。


しかし、m_data_maxとm_data_totalはどちらもCArrayObjでプロテクトされており、ゲッターしか持っておらず、アルゴリズムにはセッターが必要であるため、それほど些細なことではないことに気づきました。
m_data_maxもCArrayObjでは少し違った使われ方をしています。

しかし、とにかく、

class SubClass : private SuperClass


CArrayObjを使用 する唯一の理由は、メモリを解放するためです。
CArrayObjは他に何も使用されていません。

ほとんどがCObject *m_data[]として使用されています。

 
Amir Yacoby:


しかし、m_data_maxとm_data_totalはどちらもCArrayObjでプロテクトされており、ゲッターしか持っていないため、アルゴリズムにはセッターが必要である。
m_data_maxもCArrayObjでは少し違った使われ方をしている。

しかし、とにかく、


CArrayObjを使用する唯一の理由は、メモリを解放することです。
CArrayObjは他に何も使用されていません。

ほとんどがCObject *m_data[]として使用されており、私の意見では拡張する十分な理由にはなりません。

あなたの意見に感謝します。同感です。CArrayObjの 使用は、この場合、ややオプションです。
多くの選択肢があります。あなたが述べたように、スーパークラスをprivateにすることもできますし、CObjectから直接継承することもできます(あなたのサンプルコード)、あるいは、中途半端にすることもできます:CArrayObjの代わりにCArrayを拡張することで、偶発的な誤用に対して安全になります(実際のソートは行われません)。
CArrayObjから必要なメソッドのほとんどは、再実装することはそれほど難しくありません。私のは、いくぶん意見的な解決策です(私は、このクラスのためにできるだけ多くのコードを再利用することにしました)。
ご自由に修正してください。

 
DictionarySingleのバージョンを更新 - オブジェクトの追加順に連続反復処理を追加し、メモリの自動管理を追加し、少しリファクタリングした。
反復処理の例:
   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);
     }

   //--- 前へ
   CDictionaryEntry<string> *node=dict.GetFirstNode();
   for(int i=0; node!=NULL; i++)
     {
      printf((string)i+":\t"+node.Value());
      node=dict.GetNextNode();
     }
   //--- 後方
   node=dict.GetLastNode();
   for(int i=0; node!=NULL; i++)
     {
      printf((string)i+":\t"+node.Value());
      node=dict.GetPrevNode();
     }
ファイル: