Features of the mql5 language, subtleties and tricks - page 47

 
Mikola_2:

Like this one?

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

The question was about an array of structures and sorting by structure fields.

 
Artyom Trishkin:

Has anyone done resource-efficient sorting of an array of structures by any (not string) given field of the structure?

Suppose there is a structure with three fields int, datetime and double, and there is an array filled with data consisting of this structure. In each cell of the array, the fields of the structure are populated.

How to sort this array by any of these fields?

You create array double[][2], fill it as { fieldvalue, arrayindex }. Sort by regular ArraySort (by first change). And then you arrange structures in array according to indexes. I think this is the fastest way of all possible ways in MQL.
 
Alexey Navoykov:
Create array double[][2], fill it as { fieldvalue, arrayindex }. Sort by regular ArraySort (by first change). And then you sort structures in array according to indexes.
I wanted to bypass this method. I thought, maybe there are other ways.
 
Artyom Trishkin:
I wanted to bypass this method. I thought, maybe there are other ways.

Why bypass it? You can't think of anything faster, because the sorting is done by a native function.

 
Alexey Navoykov:

Why bypass it? You can't think of anything faster, because the sorting is done by a native function.

Basically, I started with it. I thought, maybe somebody has invented a nice way to sort an array of structures by any field.
 
Artyom Trishkin:

Has anyone done resource-efficient sorting of an array of structures by any (not string) given field of the structure?

Suppose there is a structure with three fields int, datetime and double, and there is an array filled with data consisting of this structure. In each cell of the array, the fields of the structure are populated.

How to sort this array by any of these fields?

Hi, if you need some kind of universal sorting function that can sort an array of complex data type, that's impossible in principle.

If you need capability of multifactor sorting of some known type, you can do it using classes, and CArrayObj in particular is designed for it.

I should add that even in languages as mature as C# the sorting of complex objects is solved via custom IComparer. So you will have to write a sorting criterion yourself anyway.

 
Artyom Trishkin:
I wanted to bypass this method. I thought, maybe there are other ways.

There are two ways.

The number one way is to set the operator <

Way number two functionaries.

 

Method number one:

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);
}
 

Method number two is similar, only the operator is completely external and is passed to sorting. It's a bit more complicated, but much more versatile.

If you need, I can give you some ideas, but only later.

Sorting just copypaste some kodobase, if you need faster, you'll have to write your own one, but you'll write it once and never worry about it again.
 
Combinator:

Method number two is similar, only the operator is completely external and is passed to sorting. It is a bit more complicated but much more versatile.


That is, you have to use pointers to functions

Reason: