Function - Method for sorting an array of structures. Prize 10$ - page 8

 
Georgiy Merts:

Personally, I wrote myself a long time ago a class CStructWrapper, inherited from CObject (CMyObject is actually the same, with additional debugging fields), and for sorting I use a standard function.

If I need an array of structures, I declare a derived class based on this template. In it, I declare a function for comparing the necessary fields of the structure. And then - I use a standard class of an array of objects with sorting.

Created objects can be copied directly from structures using assignment operator. If necessary, I copy them.

Unfortunately, I'm not so much experienced in OOP that I could understand your code.

 
Vladimir Pastushak:

Unfortunately, I'm not yet strong enough in OOP to understand your code.

It's just a class that contains our structure inside.

And all sorts of copy operators, allowing to use the assignment sign (=) directly between the object and the structure.

When I need an array of structures - I create an array of such objects. Each one has the required structure. In addition, a comparison function is defined in this class, which is necessary for sorting and searching. All, then standard functions of CArrayObj class are used

 
Vladimir Pastushak:

Unfortunately, I'm not yet strong enough in OOP to understand your code.

Well, implement the method without OOP. Don't worry, you can take "quick sorting" method from SB( there are a lot ofsorting algorithms, someone uploaded a video like visualization of different algorithms, everyone is better in some situation, but this one is optimal and most widely used) and change it for your structure, here you should choose, by which field of structure you will compare more vs less. approximately like this (say, by some stringyour_value)

//+------------------------------------------------------------------+
//| Method QuickSort                                                 |
//+------------------------------------------------------------------+
void CArrayString::QuickSort(int beg,int end,const int mode)
  {
   int    i,j;
   string p_string;
   string  YOUR_STRUCT t_string;
//--- check
   if(beg<0 || end<0)
      return;
//--- sort
   i=beg;
   j=end;
   while(i<end)
     {
      //--- ">>1" is quick division by 2
      p_string=m_data[(beg+end)>>1].your_value;
      while(i<j)
        {
         while(m_data[i].your_value<p_string)
           {
            //--- control the output of the array bounds
            if(i==m_data_total-1)
               break;
            i++;
           }
         while(m_data[j].your_value>p_string)
           {
            //--- control the output of the array bounds
            if(j==0)
               break;
            j--;
           }
         if(i<=j)
           {
            t_string=m_data[i];
            m_data[i++]=m_data[j];
            m_data[j]=t_string;
            //--- control the output of the array bounds
            if(j==0)
               break;
            j--;
           }
        }
      if(beg<j)
         QuickSort(beg,j);
      beg=i;
      j=end;
     }
  }
 
Vladimir Pastushak:

Unfortunately, I'm not yet strong enough in OOP to understand your code.

But at least you're good at distinguishing *** from ***?

 
Vladimir Pastushak:

Unfortunately now even the methods that fxsaber suggested don't work anymore.

And I'm looking for methods of sorting an array of structures. Does anyone have any working variants ?

I think such a workaround to the language limitation would work.

#property strict

// Сортировка массива структур и указателей на объекты по (под-) полю/методу.
#define  ArraySortStruct(T, ARRAY, FIELD)                                         \
{                                                                                \
  class SORT                                                                     \
  {                                                                              \
  private:                                                                       \
    static void Swap( T &Array[], const int i, const int j )                     \
    {                                                                            \
      const T Temp = Array[i];                                                   \
                                                                                 \
      Array[i] = Array[j];                                                       \
      Array[j] = Temp;                                                           \
                                                                                 \
      return;                                                                    \
    }                                                                            \
                                                                                 \
    static int Partition( T &Array[], const int Start, const int End )           \
    {                                                                            \
      int Marker = Start;                                                        \
                                                                                 \          
      for (int i = Start; i <= End; i++)                                         \
        if (Array[i].##FIELD <= Array[End].##FIELD)                              \
        {                                                                        \
          SORT::Swap(Array, i, Marker);                                          \
                                                                                 \
          Marker++;                                                              \
        }                                                                        \
                                                                                 \
       return(Marker - 1);                                                       \
    }                                                                            \
                                                                                 \
    static void QuickSort( T &Array[], const int Start, const int End )          \
    {                                                                            \
      if (Start < End)                                                           \
      {                                                                          \
        const int Pivot = Partition(Array, Start, End);                          \
                                                                                 \
        SORT::QuickSort(Array, Start, Pivot - 1);                                \
        SORT::QuickSort(Array, Pivot + 1, End);                                  \
      }                                                                          \
                                                                                 \
      return;                                                                    \
    }                                                                            \
                                                                                 \
  public:                                                                        \
    static void Sort( T &Array[], int Count = WHOLE_ARRAY, const int Start = 0 ) \
    {                                                                            \
      if (Count == WHOLE_ARRAY)                                                  \
        Count = ::ArraySize(Array);                                              \
                                                                                 \
      SORT::QuickSort(Array, Start, Start + Count - 1);                          \
                                                                                 \
      return;                                                                    \
    }                                                                            \
  };                                                                             \
                                                                                 \
  SORT::Sort(ARRAY);                                                             \
}

void OnStart()
{
  MqlRates Rates[];
  
  CopyRates(_Symbol, PERIOD_CURRENT, 0, 5, Rates); // Взяли бары
  
  Print("\nБары без сортировки - как получили.");
  ArrayPrint(Rates);
  
  Print("\nСортируем по open-цене.");
  ArraySortStruct(MqlRates, Rates, open);
  ArrayPrint(Rates);

  Print("\nСортируем по high-цене.");
  ArraySortStruct(MqlRates, Rates, high);
  ArrayPrint(Rates);

  Print("\nСортируем по времени.");
  ArraySortStruct(MqlRates, Rates, time);
  ArrayPrint(Rates);
}
 
Dmitry Fedoseev:

But at least you're good at distinguishing *** from ***?

Just like people... I think you have me confused with someone else...

 
Vladimir Pastushak:

So do people... I think you have me confused with someone else...

That's the thing: I think I am. But I'm not.

 
Dmitry Fedoseev:

That's the thing, it "seems". But I'm not confused.

What's all this "friction" about? What does it have to do with the subject?

 
Сергей Таболин:

What's the point of all this "friction"? What does this have to do with the subject?

Why? Is there a separate topic for this?

 
Aleksey Mavrin:

Well, implement the method without OOP. Don't go too far, take the "quick sort" method from SB

fxsaber:

I think such a workaround to the language limitation will do.

Thanks, friends!

Got it into my hole.