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.

Razón de la queja: