Особенности языка mql5, тонкости и приёмы работы - страница 47

 
Mikola_2:

Типа вот этого?

https://www.mql5.com/ru/code/9336

Вопрос был о массиве структур и сортировке по полям структур.

 
Artyom Trishkin:

Кто-нибудь делал не затратную по ресурсам сортировку массива структур по любому (не string) заданному полю структуры?

Допустим, есть структура с тремя полями int, datetime и double, и есть массив, заполненный данными, состоящими из этой структуры. В каждой ячейке массива поля структуры заполнены.

Как отсортировать этот массив по любому из этих полей?

Создаёте массив double[][2], заполняете его как { fieldvalue, arrayindex }.  Сортируете штатным ArraySort (по первому изменению).  Ну и дальше уже расставляете структуры в массиве в соответствии с индексами.  Полагаю, это самый быстрый из всех возможных способов в MQL.
 
Alexey Navoykov:
Создаёте массив double[][2], заполняете его как { fieldvalue, arrayindex }.  Сортируете штатным ArraySort (по первому изменению).  Ну и дальше уже расставляете структуры в массиве в соответствии с индексами.
Этот способ хотел как раз обойти. Думал, может есть иные способы.
 
Artyom Trishkin:
Этот способ хотел как раз обойти. Думал, может есть иные способы.

Почему обойти то?  Быстрее ничего не придумать, т.к. сортировку производит нативная функция.

 
Alexey Navoykov:

Почему обойти то?  Быстрее ничего не придумать, т.к. сортировку производит нативная функция.

В принципе, и начинал сразу с этого. Подумалось, вдруг кто выдумал красивый способ сортировки массива структур по любому полю.
 
Artyom Trishkin:

Кто-нибудь делал не затратную по ресурсам сортировку массива структур по любому (не string) заданному полю структуры?

Допустим, есть структура с тремя полями int, datetime и double, и есть массив, заполненный данными, состоящими из этой структуры. В каждой ячейке массива поля структуры заполнены.

Как отсортировать этот массив по любому из этих полей?

Привет, если нужна некая универсальная функция сортировки, которая способна сортировать массив сложного типа данных, то это невозможно в принципе.

Если тебе нужна возможность многофакторной сортировки заранее известного типа - то это можно сделать штатными средствами через классы и в частности CArrayObj на это и заточен.

Добавлю, что даже в таких взрослых языках как C# сортировка сложных объектов решается через пользовательские IComparer. Т.е. писать самому критерий сортировки все равно придется.

 
Artyom Trishkin:
Этот способ хотел как раз обойти. Думал, может есть иные способы.

Есть, целых два.

Способ номер раз - задание оператора <

Способ номер два функторы.

 

Способ номер раз:

template <typename t>
void Sort(t& a[], bool ascending = true)
{
  if (ascending) SortShellUp(a);
  else           SortShellDn(a);
}

template <typename t>
void SortShellUp(t& a[])
{
  t tmp;
  int n[]={9,5,3,2,1};
  int i,j,k,g;
  int Len=ArraySize(a);
  for(k=0;k<5;k++)
  {
    g=n[k];
    for(i=g;i<Len;i++)
    {
      tmp=a[i];
      for(j=i-g;j>=0 && tmp<a[j];j-=g)
      {
        a[j+g]=a[j];
      }
      a[j+g]=tmp;
    }
  }
}

template <typename t>
void SortShellDn(t& a[])
{
  t tmp;
  int n[]={9,5,3,2,1};
  int i,j,k,g;
  int Len=ArraySize(a);
  for(k=0;k<5;k++)
  {
    g=n[k];
    for(i=g;i<Len;i++)
    {
      tmp=a[i];
      for(j=i-g;j>=0 && a[j]<tmp;j-=g)
      {
        a[j+g]=a[j];
      }
      a[j+g]=tmp;
    }
  }
}

struct DrawData
{
   float price;
   float percent;
   
   bool operator < (const DrawData& right) const
   {
      return price < right.price;
   }
};

{
   DrawData items[];
   // filling
   Sort(items);
}
 

Способ номер два похож, только оператор совсем внешний и передается в сортировку. Он немного сложнее но намного более универсальный.

Если надо, могу накидать, но только позже.

Сортировка просто копипаст какой-то из кодобазы, если надо быстрее, придется писать свою шуструю, но это один раз написать и больше не париться.
 
Комбинатор:

Способ номер два похож, только оператор совсем внешний и передается в сортировку. Он немного сложнее но намного более универсальный.


То есть - нужно использовать указатели на функции

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