Аналог JSON в MQL

 

Здравствуйте, подскажите пожалуйста, как создавать многоуровневые иерархии данных в MQL?

Для примера я взял JSON из JS с сайта developer.mozilla.org. Есть ли какой-то аналог в MQL?

{
  "squadName": "Super hero squad",
  "homeTown": "Metro City",
  "formed": 2016,
  "secretBase": "Super tower",
  "active": true,
  "members": [
    {
      "name": "Molecule Man",
      "age": 29,
      "secretIdentity": "Dan Jukes",
      "powers": [
        "Radiation resistance",
        "Turning tiny",
        "Radiation blast"
      ]
    },
    {
      "name": "Madame Uppercut",
      "age": 39,
      "secretIdentity": "Jane Wilson",
      "powers": [
        "Million tonne punch",
        "Damage resistance",
        "Superhuman reflexes"
      ]
    },
    {
      "name": "Eternal Flame",
      "age": 1000000,
      "secretIdentity": "Unknown",
      "powers": [
        "Immortality",
        "Heat Immunity",
        "Inferno",
        "Teleportation",
        "Interdimensional travel"
      ]
    }
  ]
}

Т.е. этот код выше описывает свойства команды супергероев "Super hero squad". В этой команде 3 члена и у каждого члена свои характеристики.

- - -
Аналогично, я бы хотел создать многоуровневую иерархию данных в MQL. Не смог придумать, как сделать это с помощью массивов или структур данных. Вроде в массивы нельзя засунуть разные типы данных (string, bool, double...), а структуры вроде одномерные. Хотя я не очень продвинут в MQL, может не разобрался. Подскажите пожалуйста. Желательно с простеньким примеров.

Спасибо.

 

Массивы структур:

struct Super
   {
   string squadName;
   .....
   struct Member
      {
      string name;
      int age;
      .....
      } member[];
   } super_hero_squad;
ArrayResize(super_hero_squad.member,1);
super_hero_squad.member[0].name="Molecule Man";
super_hero_squad.member[0].age=29;
 

Структура и класс могут включать в себя другие структуры и классы.

В один массив можно засунуть объекты разного типа, если эти объекты наследованы от общего типа, а массив имеет этот тип. 

 
Aleksei Stepanenko:

Массивы структур:

Dmitry Fedoseev:

Структура и класс могут включать в себя другие структуры и классы.

В один массив можно засунуть объекты разного типа, если эти объекты наследованы от общего типа, а массив имеет этот тип. 

Спасибо большое за ответы. Очень помогло.

У меня в ходе использования возник следующий вопрос. А как использовать структуру в параметрах функции?
void OnTick()
  {
// ---
// Это пример, если я хочу наполнить с помощью функции массив
   double array1[];
   double array2[];
   func(array1, array2);

// ---
// А как сделать, если я хочу наполнить структуру c помощью функции?
   struct mystruct
     {
      double         Element1;
      double         Element2;
     } myStruct[]; // Ведь обращение к элементам структуры происходит так же, как обращение к элементам массива?

   funcStruct(myStruct[].Element1, myStruct[].Element2); // Синтаксис некорректный
// Я хочу перебрать структуру myStruct[] будто это массив и наполнить члены этой структуры.
// Как мне вставить в параметры функции ссылку на структуру, которую хочу заполнить?
  }


//
void func(double & array1[], double & array2[])
  {
// В функции наполняем переданные массивы
  }

Благодарю за ответы

 

Можно весь массив передать в функцию, можно один элемент:

struct mystruct
     {
      double         Element1;
      double         Element2;
     } myStruct[];


void OnStart()
  {
//---
   func(myStruct);
   
   func2(myStruct[0]);
  }
//+------------------------------------------------------------------+

void func(mystruct & ar[])
  {
   
   ArrayResize(ar,1);

   ar[0].Element1=1;

  }
  
  
void func2(mystruct & el)
  {
   
   el.Element2=2;

  }  

Отдельные поля тоже можно передавать.

 
Dmitry Fedoseev:

Можно весь массив передать в функцию, можно один элемент:

Отдельные поля тоже можно передавать.

Спасибо. То, что нужно )

 
Dmitry Fedoseev:

Можно весь массив передать в функцию, можно один элемент:

Отдельные поля тоже можно передавать.

И еще сразу задам вопрос в дополнение к предыдущему

Как можно сортировать содержимое структур?  Для сортировки массивов к примеру есть встроенная функция ArraySort()

А как отсортировать структуру MainData[1].PricesData[], чтобы к примеру элемент priceLevel в MainData[1].PricesData[] шел в порядке возрастания?

 
yar.forex:

И еще сразу задам вопрос в дополнение к предыдущему

Как можно сортировать содержимое структур?  Для сортировки массивов к примеру есть встроенная функция ArraySort()

А как отсортировать структуру MainData[1].PricesData[], чтобы к примеру элемент priceLevel в MainData[1].PricesData[] шел в порядке возрастания?

Два варианта:

1. Находим функцию быстрой сортировки в кодабазе или в терминале в Include/Arrays/ArrayObj.mqh (имя метода - QuickSort) и переделываем ее под работу с массивом своих структур.

2. Используем двухмерный массив double. Изменяем его размер соответственно размеру массива структур, элементам первого измерения присваиваем значения поля, по которому надо отсортировать, элементам второго измерениея присваиваем индекс элемента в массиве структур. Сортируем этот массив double функцией ArraySort(). После этого обращаемся к элементам массива структур через "прокладку".  

myStruct[(int)d[i][1]].Element1

То есть исходный массив вообще не трогаем. 

Если надо, то можно и переместить элементы в соответствии с полученным порядком, но это лишнее.

 
Dmitry Fedoseev:

Два варианта:

1. Находим функцию быстрой сортировки в кодабазе или в терминале в Include/Arrays/ArrayObj.mqh (имя метода - QuickSort) и переделываем ее под работу с массивом своих структур.

2. Используем двухмерный массив double. Изменяем его размер соответственно размеру массива структур, элементам первого измерения присваиваем значения поля, по которому надо отсортировать, элементам второго измерениея присваиваем индекс элемента в массиве структур. Сортируем этот массив double функцией ArraySort(). После этого обращаемся к элементам массива структур через "прокладку".  

То есть исходный массив вообще не трогаем. 

Если надо, то можно и переместить элементы в соответствии с полученным порядком, но это лишнее.

Да, круто, с использованием двухмерного массива double сработало )

Подскажите еще пожалуйста

// Предположим, у меня есть многоуровневая структура
struct mainData
  {
   int               magic;
   struct            pricesData
     {
      double         priceLevel;
      struct            tpData
        {
         double         TPlevel;
         double         TPVolume;
        } TPData[10];
     } PricesData[10];
  } MainData[10];


//
void              OnTick()
  {

// Предположим, я хочу сейчас работать с MainData[1].PricesData[10].TPData[]
   MainData[1].PricesData[10].TPData[0].TPlevel = 1.21000;
   MainData[1].PricesData[10].TPData[1].TPlevel = 1.21100;
// ...

// Можно ли ввести переменную, чтобы чтобы это все не писать и код проще читался?
int workingNow = MainData[1].PricesData[10].TPData; // Синтаксис неверный
    workingNow[0].TPlevel = 1.21000;
    workingNow[1].TPlevel = 1.21100;
// Что-то вроде этого?

  }
 

Попробуйте решить вопрос при помощи функций:

double value=GetValue(MainData,1,2,2,1);
SetValue(MainData,3,4,2,1,value);



double GetValue(mainData &eData[], int eIndex1, int eIndex2, int eIndex3, int eIndex4)
   {
   return(eData[eIndex1].PricesData[eIndex2].TPData[eIndex3].TPlevel[eIndex4]); 
   }

void SetValue(mainData &eData[], int eIndex1, int eIndex2, int eIndex3, int eIndex4, double eValue)
   {
   eData[eIndex1].PricesData[eIndex2].TPData[eIndex3].TPlevel[eIndex4]=eValue; 
   }
 
yar.forex:

Да, круто, с использованием двухмерного массива double сработало )

Подскажите еще пожалуйста

Нет такого способа. Через функцию надо.

Причина обращения: