Función - Método para ordenar una matriz de estructuras. Premio 10$

 

Hola a todos, hay una función escrita por fxsaber

template <typename T>                                       
void ArrayReindex( T &Array[], const double &TmpSort[][2] )
{                         
  T TmpArray[];
  
  for (int x = ::ArrayResize(TmpArray, ::ArrayRange(TmpSort, 0)) - 1; x >= 0; x--)
    TmpArray[x] = Array[(int)(TmpSort[x][1] + 0.1)];
    
  ::ArraySwap(Array, TmpArray);
              
  return;     
}             

// Сортировка массива структур и указателей на объекты по (под-) полю/методу.
#define  ArraySortStruct(ARRAY, FIELD)                                      \
{                                                                          \
  double TmpSort[][2];                                                     \
                                                                           \
  for (int x =::ArrayResize(TmpSort, ::ArraySize(ARRAY)) - 1; x >= 0; x--) \
  {                                                                        \
    TmpSort[x][0] = (double)ARRAY[x].FIELD;                                \
    TmpSort[x][1] = x;                                                     \
  }                                                                        \
                                                                           \
  ::ArraySort(TmpSort);                                                    \
  ::ArrayReindex(ARRAY, TmpSort);                                          \
}                                  


Funciona sin problemas en MT 5, pero en MT 4 se queja deArraySwap porque Mql 4 no lo soporta...


¿Tal vez alguien tiene algunas variantes de estructuras de array de ordenación universal que funcionen en MT 5 y MT 4?


Todavía puedo ofrecer una recompensa para la aplicación más rápida de 10 $.

Документация по MQL5: Операции с массивами / ArraySort
Документация по MQL5: Операции с массивами / ArraySort
  • www.mql5.com
//| Получение значений границ для тиковых объемов                    | //| Custom indicator initialization function                         | //| Custom indicator iteration function                              | //
 

Necesitas escribir tu estructura como una clase que herede de CObject y escribir tu método Compare, entonces usa CArrayObj. Esta será la opción más rápida.

Y sobre ArraySwap aquí - https://www.mql5.com/ru/docs/array/arrayswap no debe ser difícil de escribir dicha función para MT4.

 
Dmitry Fedoseev:

Necesitas escribir tu estructura como una clase que herede de CObject y escribir tu método Compare, entonces usa CArrayObj. Esta será la opción más rápida.

Y sobre ArraySwap aquí - https://www.mql5.com/ru/docs/array/arrayswap no debe ser difícil de escribir dicha función para MT4.

He leído esta información.

Estamos hablando de un array de estructuras, no de un simple array.

 
Vladimir Pastushak:

He leído esta información.

Estamos hablando de un array de estructuras, no de un simple array.

¿EsCArrayObj un simple array?

 
Dmitry Fedoseev:

¿Es CArrayObj un simple array?

No, no tengo una relación amistosa con OOP.

 

La variante de @fxsaber será la más rápida, porque el compilador desplegará las macros en código completo

Para evitar la duplicación de código, envuelva las ordenaciones necesarias por campos requeridos en funciones y utilice


Las variantes con herencia deCObject serán muchas veces más lentas, tendrás que añadir los correspondientes métodos de Comparación

 
Igor Makanu:

La variante de @fxsaber será la más rápida, porque el compilador desplegará las macros al código completo

Para evitar la duplicación de código, envuelva las ordenaciones necesarias por campos requeridos en funciones y utilice


y las variantes con herenciaCObject serán muchas veces más lentas, además de tener que añadir los correspondientes métodos Compare

Allí copiamos los datos de un array a otro y luego barajamos los índices. Tal vez sea más rápido usar ArraySort().

 

Y aquí hay una opción: modificar la función para adaptarla a su estructura:

#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

struct SMy{
   int x1;
   int x2;
};

SMy s[3]={{4,44},{2,22},{3,33}};

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart(){
   
   SortHoareUp(s);
   
   for(int i=0;i<3;i++){
      Alert(s[i].x1," ",s[i].x2);
   }
   
}


void SortHoareUp(SMy  &aAr[])
  {
   HoareUp(aAr,0,ArraySize(aAr)-1);
  }

void HoareUp(SMy  &aAr[],int aLeft,int aRight)
  {
   SMy tmp;
   int i=aLeft;
   int j=aRight;
   
   int xx=aAr[(aLeft+aRight)/2].x1; // int заменить на тип поля по которому выполняется сравнение
   
   do
     {
   while(i<aRight && aAr[i].x1<xx)i++;
   while(j>aLeft && xx<aAr[j].x1)j--;
   if(i<=j)
     {
      tmp=aAr[i];
      aAr[i]=aAr[j];
      aAr[j]=tmp;
      i++;
      j--;
     }
  }
   while(i<=j);
   if(aLeft<j)HoareUp(aAr,aLeft,j);
   if(i<aRight)HoareUp(aAr,i,aRight);
}
 

Pero con CObjArray

#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

#include <Arrays/ArrayObj.mqh>

class CMyClass:public CObject{
   public:
      int x1;
      int x2;
      int x3;     
      CMyClass(int ax1,int ax2,int ax3){
         x1=ax1;
         x2=ax2;         
         x3=ax3;           
      }
      int Compare(const CObject *node,const int mode=0)const{
         const CMyClass * t=node;
         if(mode==0 && t.x1>this.x1){
            return(1);
         }
         if(mode==1 && t.x1<this.x1){
            return(1);         
         }
         return(-1);
      }      
};

CMyClass * tmp;
CArrayObj a;

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart(){

   a.Add(new CMyClass(1,11,111));
   a.Add(new CMyClass(2,22,222));   
   a.Add(new CMyClass(3,33,333));   
   
   Alert("===");
   
   Al(1);
   a.Sort(0);   
   Al(2);
   a.Sort(1);      
   Al(3);

   
  }
//+------------------------------------------------------------------+

void Al(int n){
   Alert("-"+(string)n+"-");
   for(int i=0;i<a.Total();i++){
      tmp=a.At(i);
      Alert(tmp.x1," ",tmp.x2," ",tmp.x3);
   }   
}
 
Dmitry Fedoseev:

Pero esta variante - para cambiar la función para adaptarse a su estructura:

no es una opción en absoluto - esta es una solución común a un problema particular, la portabilidad de tales soluciones para su uso posterior será proporcional a la escritura desde cero )))

El código del primer post se implementa copiando, si la tarea es realizar la ordenación en 2 o 3 lugares

o, como he sugerido anteriormente, si va a utilizar la ordenación por diferentes campos en diferentes secciones de código, sería mejor crear funciones envolventes para las macros sugeridas


HH: Las fuentes de C# con todas las clases base en el sitio de Microsoft, hay clases, y son similares a las interfaces en SB, pero por desgracia, no finalizaron SB - dijeron hazlo tú mismo ;)

 
Igor Makanu:

no es una opción en absoluto - se trata de una solución común a un problema particular, la portabilidad de tales soluciones para su uso posterior será comparable a escribir desde cero )))

El código del primer post se puede implementar copiando si la tarea es realizar la clasificación en 2 o 3 fragmentos de código

o, como he sugerido anteriormente, si va a utilizar la ordenación por diferentes campos en diferentes secciones de código, sería mejor crear funciones envolventes para las macros sugeridas


HH: Las fuentes de C# con todas las clases básicas en el sitio de Microsoft, hay clases, y son similares a las interfaces en SB, pero por desgracia, no finalizaron SB - dijeron hazlo tú mismo ;)

Cambia el tipo de variable en un lugar y el compilador mostrará errores en los otros tres: cambia el nombre del campo. Se podría pensar que docenas de estructuras tienen que ser ordenadas en algún lugar. Sí, lo más probable es que una estructura requiera una clasificación.