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

 
Dmitry Fedoseev:

Change the variable type in one place and the compiler will show errors in the other three - change the field name. You would think there are dozens of structures that need to be sorted. Yes, one structure most likely requires sorting.

No, do not set the task this way

set the following task: use your example to sort through the structure that has dozens of fields by each field

let it be a structure that contains all the properties of the order "four" (OrderStoploss(), OrderTakeProfit(), OrderOpenTime()....) - there are a dozen of them

And reproduce the sorting of an array of such structures by each field with your examples? - imho, your code will weigh quite a bit, and I wrote above that it won't be possible to reuse this code

 
Igor Makanu:

No, that's not how you should set the task.

set the following task: using your example, sort the structure that has dozens of fields by each field

let it be a structure containing all the properties of the order "four" (OrderStoploss(), OrderTakeProfit(), OrderOpenTime()....) - there are a dozen of them

And reproduce the sorting of an array of such structures by each field with your examples? - imho, your code will weigh quite a bit. I wrote above that it won't be possible to use this code repeatedly.

A problem from the realm of science fiction, never encountered in practice.

You can make a separate field to sort by and before sorting, copy into it from the field you want to sort by.

 
Vladimir Pastushak:

In MT 5 it works without problems in MT 4 it blamesArraySwap because Mql 4 does not support it...

#ifndef __MQL5__
  template <typename T>
  void ArraySwap( T &Array1[], T &Array2[] )
  {
    T ArrayTmp[];

    ArrayCopy(ArrayTmp, Array1);
    ArrayFree(Array1);

    ArrayCopy(Array1, Array2);

    ArrayFree(Array2);
    ArrayCopy(Array2, ArrayTmp);

    return;
  }
#endif // __MQL5__
 
Dmitry Fedoseev:

A challenge from the realm of fiction.

No, it is possible to use MQL, just as you suggested using SB

But the problem will be that this code will be written for a certain task

If we give an example - the terminal panel with orders has been reproduced as a window in MQL, the sorting has been done, everything spins, everything works

And if you want to use a part of the code to display the "optimization" panel of the tester, you will get a carload of changes. It's easier to write the code from scratch, including sorts, and you will want to have human readable field names? - otherwise you need to be the author of a well-known "kernel" to keep in mind all the names of identifiers in the form of Abyrwalg (A Dog's Heart)

)))

 
Igor Makanu:

No, it is possible to use MQL, just as you suggested using SB

but the problem will be that this code will be written for a specific task

If we give an example, the terminal panel with orders has been reproduced as a window in MQL, the sorting has been done, everything spins, everything works

And if you want to use a part of the code to display the "optimization" panel of the tester, you will get a carload of changes. It's easier to write the code from scratch, including sorts, and you will want to have human readable field names? - otherwise you need to be the author of a well-known "kernel" to keep in mind all the names of identifiers in the form of Abyrwalgh (A Dog's Heart)

)))

Anything that can be misunderstood will be misunderstood. I meant not the possibility/impossibility, but the practical need for it, i.e. the occurrence of this task.

It's not my idea that for each structure you must write your own Compare().

 

Why sort the array/vector of thick structures into different fields ?

let it lie as it is, it has the right to be even const :-) and for different purposes you can build indexes

/// код не проверял - написал "с руки", демонстрировать идею
template <typename T>
int
ArrayIndexate(const T &arr[],int &index[],int (*compare)(const T&,const T&))
{
   /// инициализуем индексный массив
   int size=ArraySize(arr);
   if (size==-1 || ArrayResize(index,size)==-1) {
      return -1;
   }
   for(int i=0;i<size;i++)
      index[i]=i;
   /// "пузырёк" - замените более быстрым методом
   for(int i=0;i<size;i++) {
      for(int j=i+1;j<size;j++) {
         if ( compare(arr[index[i]],arr[index[j]] ) > 0 ) {
            int swap=index[i];
            index[i]=index[j];
            index[j]=swap;
         }
      }
   }
   // в массиве index[] теперь лежат индексы элементов arr[]
   return size;   
}
 
Dmitry Fedoseev:

It's not my idea to write a different Compare() for each structure.

That's exactly how it is, or rather I don't know any other way, and this method will be tied to a specific task

and the author wants a universal solution for 10 quid, well, let's wait and see if something clears up

 
Maxim Kuznetsov:

Why sort the array/vector of thick structures into different fields ?

Let it lie as it is, it has the right to be even const :-) and for different purposes you can build indexes

Someone will write now ... that it's so inconvenient for me ... that we are not housewives, but superdevelopers, and we must use all possibilities of modern programming technologies, while an additional array is something like the Middle Ages ...

Although, personally, I like this option better.

#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}};
double sa[][2];

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart(){
   int size=ArraySize(s);
   ArrayResize(sa,size);
   for(int i=0;i<size;i++){
      sa[i][0]=s[i].x1; // поле по которому сортировать
      sa[i][1]=i;
   }
   ArraySort(sa);
   
   Alert("===");
   for(int i=0;i<size;i++){
      int ii=(int)sa[i][1];
      Alert(s[ii].x1," ",s[ii].x2);
   }
   
}

 
fxsaber:

No way:
1) It's enough to insert ArrayCopy into conditional compilation, not ArraySwap.
2) ArrayCopy needs to be written in custom one, as standard one doesn't support NonPod structures.
3) We need one more conditional compilation for ArrayResize multi-domain array (function gives different results for different MT versions)

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

It won't:

The answer was not for all occasions. Most people close.