Fonction - Méthode pour trier un tableau de structures. Prix 10$.

 

Salut à tous, il existe une fonction écrite par 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);                                          \
}                                  


Fonctionne sans problèmes dans MT 5, mais dans MT 4 il se plaint deArraySwap parce que Mql 4 ne le supporte pas...


Peut-être quelqu'un a-t-il des variantes de structures de tableaux de tri universel fonctionnant dans MT 5 et MT 4 ?


Je peux encore offrir une récompense pour l'implémentation la plus rapide de 10$.

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

Vous devez écrire votre structure comme une classe qui hérite de CObject et écrire votre méthode Compare, puis utiliser CArrayObj. C'est l'option la plus rapide.

Et à propos de ArraySwap ici - https://www.mql5.com/ru/docs/array/arrayswap ne devrait pas être difficile d'écrire une telle fonction pour MT4.

 
Dmitry Fedoseev:

Vous devez écrire votre structure comme une classe qui hérite de CObject et écrire votre méthode Compare, puis utiliser CArrayObj. C'est l'option la plus rapide.

Et à propos de ArraySwap ici - https://www.mql5.com/ru/docs/array/arrayswap ne devrait pas être difficile d'écrire une telle fonction pour MT4.

J'ai lu cette information.

Nous parlons d'un tableau de structures, pas d'un simple tableau.

 
Vladimir Pastushak:

J'ai lu ces informations.

Nous parlons d'un tableau de structures, pas d'un simple tableau.

CArrayObj est-il un simple tableau ?

 
Dmitry Fedoseev:

CArrayObj est-il un simple tableau ?

Non, je n'ai pas de relation amicale avec OOP.

 

La variante de @fxsaber sera la plus rapide, car le compilateur déploiera les macros au code complet

Pour éviter la duplication du code, intégrez les tris nécessaires par les champs obligatoires dans des fonctions et utilisez


les variantes avec héritage deCObject seront beaucoup plus lentes, vous devrez ajouter les méthodes Compare correspondantes

 
Igor Makanu:

La variante de @fxsaber sera la plus rapide, car le compilateur déploiera les macros en code complet

Pour éviter la duplication du code, intégrez les tris nécessaires par les champs obligatoires dans des fonctions et utilisez


et les variantes avec l'héritageCObject seront beaucoup plus lentes, de plus vous devrez ajouter les méthodes Compare correspondantes

Là, nous copions les données d'un tableau à l'autre, puis nous mélangeons les index. Il sera peut-être plus rapide d'utiliser ArraySort().

 

Et voici une option : modifiez la fonction pour l'adapter à votre structure :

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

Mais avec 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:

Mais cette variante - changer la fonction pour l'adapter à votre structure :

n'est pas du tout une option - il s'agit d'une solution commune à un problème particulier, la portabilité de telles solutions pour une utilisation ultérieure sera proportionnelle à l'écriture à partir de zéro ;)))

Le code du premier post est implémenté par copie, si la tâche est d'effectuer un tri à 2 ou 3 endroits

ou, comme je l'ai suggéré plus haut, si vous avez l'intention d'utiliser le tri par différents champs dans différentes sections de code, il serait préférable de créer des fonctions enveloppantes pour les macros proposées


HH : Les sources de C# avec toutes les classes de base sur le site de Microsoft, il y a des sortes, et elles sont similaires aux interfaces dans SB, mais hélas, ils n'ont pas finalisé SB - ils ont dit faites-le vous-même ;)

 
Igor Makanu:

ce n'est pas une option du tout - c'est une solution commune à un problème particulier, la portabilité de telles solutions pour une utilisation ultérieure sera comparable à l'écriture à partir de zéro ;)))

Le code du premier post peut être implémenté par copie si la tâche consiste à effectuer le tri en 2 ou 3 fragments de code.

ou, comme je l'ai suggéré plus haut, si vous avez l'intention d'utiliser le tri par différents champs dans différentes sections de code, il serait préférable de créer des fonctions enveloppantes pour les macros proposées


HH : Les sources de C# avec toutes les classes de base sur le site de Microsoft, il y a des sortes, et elles sont similaires aux interfaces dans SB, mais hélas, ils n'ont pas finalisé SB - ils ont dit faites-le vous-même ;)

Changez le type de variable à un endroit et le compilateur affichera des erreurs dans les trois autres - changez le nom du champ. On pourrait penser que des dizaines de structures doivent être triées quelque part. Oui, il est fort probable qu'une structure nécessite un tri.