Funktion - Methode zum Sortieren eines Arrays von Strukturen. Preis 10$

 

Hallo zusammen, es gibt eine von fxsaber geschriebene Funktion

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


Funktioniert ohne Probleme in MT 5, aber in MT 4 beschwert es sich überArraySwap, weil Mql 4 es nicht unterstützt...


Vielleicht hat jemand einige Varianten der universellen Sortierung Array Strukturen arbeiten in MT 5 und MT 4 ?


Ich kann noch eine Belohnung für die schnellste Umsetzung von 10$ anbieten

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

Sie müssen Ihre Struktur als Klasse schreiben, die von CObject erbt und Ihre Compare-Methode schreiben, und dann CArrayObj verwenden. Dies ist die schnellste Option.

Und über ArraySwap hier - https://www.mql5.com/ru/docs/array/arrayswap sollte nicht schwierig sein, solche Funktion für MT4 zu schreiben.

 
Dmitry Fedoseev:

Sie müssen Ihre Struktur als Klasse schreiben, die von CObject erbt und Ihre Compare-Methode schreiben, und dann CArrayObj verwenden. Dies ist die schnellste Option.

Und über ArraySwap hier - https://www.mql5.com/ru/docs/array/arrayswap sollte nicht schwierig sein, solche Funktion für MT4 zu schreiben.

Ich habe diese Informationen gelesen.

Wir sprechen von einem Array von Strukturen, nicht von einem einfachen Array.

 
Vladimir Pastushak:

Ich habe diese Informationen gelesen.

Wir sprechen hier von einem Array von Strukturen, nicht von einem einfachen Array.

IstCArrayObj ein einfaches Array?

 
Dmitry Fedoseev:

Ist CArrayObj ein einfaches Array?

Nein, ich habe keine freundschaftliche Beziehung zu OOP.

 

Die Variante von @fxsaber wird die schnellste sein, da der Compiler die Makros in den gesamten Code einfügt

Um Code-Duplizierung zu vermeiden, verpacken Sie notwendige Sortierungen nach erforderlichen Feldern in Funktionen und verwenden Sie


Varianten mit Vererbung vonCObject werden um ein Vielfaches langsamer sein, Sie müssen die entsprechenden Vergleichsmethoden hinzufügen

 
Igor Makanu:

Die Variante von @fxsaber ist die schnellste, da der Compiler die Makros in den vollständigen Code einfügt.

Um Code-Duplizierung zu vermeiden, verpacken Sie notwendige Sortierungen nach erforderlichen Feldern in Funktionen und verwenden Sie


und die Varianten mitCObject-Vererbung werden um ein Vielfaches langsamer sein, außerdem müssen Sie die entsprechenden Vergleichsmethoden hinzufügen

Dort kopieren wir Daten von einem Array in ein anderes und mischen dann die Indizes. Vielleicht geht es mit ArraySort() schneller.

 

Und hier ist eine Möglichkeit: Sie können die Funktion an Ihre Struktur anpassen:

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

Aber mit 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:

Aber diese Variante - um die Funktion zu ändern, um Ihre Struktur zu passen:

ist überhaupt keine Option - dies ist eine gängige Lösung für ein bestimmtes Problem, die Übertragbarkeit solcher Lösungen für die spätere Verwendung wird mit dem Schreiben von Grund auf angemessen sein )))

Der Code im ersten Beitrag wird durch Kopieren implementiert, wenn die Aufgabe darin besteht, eine Sortierung an 2 oder 3 Stellen durchzuführen

oder, wie ich oben vorgeschlagen habe, wenn Sie die Sortierung nach verschiedenen Feldern in verschiedenen Codeabschnitten verwenden wollen, wäre es besser, Wrapper-Funktionen für die vorgeschlagenen Makros zu erstellen


HH: Die Quellen von C# mit allen Basisklassen auf der Microsoft-Seite, es gibt verschiedene, und sie sind ähnlich wie die Schnittstellen in SB, aber leider haben sie SB nicht fertiggestellt - sie sagten, mach es selbst ;)

 
Igor Makanu:

überhaupt keine Option - dies ist eine allgemeine Lösung für ein bestimmtes Problem, die Übertragbarkeit solcher Lösungen für eine spätere Verwendung ist vergleichbar mit dem Schreiben von Grund auf )))

Der Code im ersten Beitrag kann durch Kopieren implementiert werden, wenn die Aufgabe darin besteht, die Sortierung in 2 oder 3 Codefragmenten durchzuführen

oder, wie ich oben vorgeschlagen habe, wenn Sie die Sortierung nach verschiedenen Feldern in verschiedenen Codeabschnitten verwenden wollen, wäre es besser, Wrapper-Funktionen für die vorgeschlagenen Makros zu erstellen


HH: Die Quellen von C# mit allen Basisklassen auf der Microsoft-Seite, es gibt verschiedene, und sie sind ähnlich wie die Schnittstellen in SB, aber leider haben sie SB nicht fertiggestellt - sie sagten, mach es selbst ;)

Ändern Sie den Variablentyp an einer Stelle, und der Compiler zeigt an den anderen drei Stellen Fehler an - ändern Sie den Feldnamen. Man sollte meinen, dass Dutzende von Strukturen irgendwo sortiert werden müssen. Ja, höchstwahrscheinlich muss eine Struktur sortiert werden.

Grund der Beschwerde: