Funzione - Metodo per ordinare un array di strutture. Premio 10$ - pagina 2

 
Dmitry Fedoseev:

Cambia il tipo di variabile in un posto e il compilatore mostrerà errori negli altri tre - cambia il nome del campo. Si potrebbe pensare che ci sono decine di strutture che devono essere ordinate. Sì, una struttura richiede molto probabilmente un ordinamento.

No, non impostare il compito in questo modo

imposta il seguente compito: usa il tuo esempio per ordinare la struttura che ha decine di campi per ogni campo

sia una struttura che contiene tutte le proprietà dell'ordine "quattro" (OrderStoploss(), OrderTakeProfit(), OrderOpenTime()....) - ce ne sono una dozzina

E riprodurre l'ordinamento di un array di tali strutture per ogni campo con i vostri esempi? - imho, il tuo codice peserà un bel po', e ho scritto sopra che non sarà possibile utilizzare questo codice ripetutamente

 
Igor Makanu:

No, non è così che si dovrebbe impostare il compito.

imposta il seguente compito: usando il tuo esempio, ordina la struttura che ha decine di campi per ogni campo

sia una struttura contenente tutte le proprietà dell'ordine "quattro" (OrderStoploss(), OrderTakeProfit(), OrderOpenTime()....) - ce ne sono una dozzina

E riprodurre l'ordinamento di un array di tali strutture per ogni campo con i vostri esempi? - imho, il tuo codice peserà un bel po'. Ho scritto sopra che non sarà possibile utilizzare questo codice ripetutamente.

Un problema da regno della fantascienza, mai incontrato nella pratica.

Puoi creare un campo separato per ordinare e prima di ordinare, copiarci dentro il campo che vuoi ordinare.

 
Vladimir Pastushak:

In MT 5 funziona senza problemi, in MT 4 dà la colpa adArraySwap perché Mql 4 non lo supporta...

#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:

Una sfida dal regno della finzione.

No, è possibile usare MQL, proprio come hai suggerito tu usando SB

Ma il problema sarà che questo codice sarà scritto per un certo compito

Se facciamo un esempio - il pannello terminale con gli ordini è stato riprodotto come finestra in MQL, l'ordinamento è stato fatto, tutto gira, tutto funziona

E se vuoi usare una parte del codice per visualizzare il pannello "ottimizzazione" del tester, avrai una vagonata di modifiche. È più facile scrivere il codice da zero, inclusi gli ordinamenti, e vorrai avere nomi di campi leggibili dall'uomo? - altrimenti bisogna essere l'autore di un noto "kernel" per tenere a mente tutti i nomi di identificatori in forma di Abyrwalg (A Dog's Heart)

)))

 
Igor Makanu:

No, è possibile usare MQL, proprio come hai suggerito tu usando SB

ma il problema sarà che questo codice sarà scritto per un compito specifico

Se facciamo un esempio, il pannello terminale con gli ordini è stato riprodotto come finestra in MQL, l'ordinamento è stato fatto, tutto gira, tutto funziona

E se vuoi usare una parte del codice per visualizzare il pannello "ottimizzazione" del tester, avrai una vagonata di modifiche. È più facile scrivere il codice da zero, inclusi gli ordinamenti, e vorrai avere nomi di campi leggibili dall'uomo? - altrimenti bisogna essere l'autore di un noto "kernel" per tenere a mente tutti i nomi di identificatori in forma di Abyrwalg (A Dog's Heart)

)))

Tutto ciò che può essere frainteso sarà frainteso. Non intendevo la possibilità/impossibilità, ma la necessità pratica, cioè il verificarsi di questo compito.

Non è una mia idea che per ogni struttura devo scrivere la mia Compare().

 

perché ordinare l'array/vettore di strutture spesse in campi diversi?

lasciatelo stare così com'è, ha il diritto di essere anche const :-) e per scopi diversi si possono costruire indici

/// код не проверял - написал "с руки", демонстрировать идею
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:

Non è una mia idea scrivere una Compare() diversa per ogni struttura.

È esattamente così, o meglio non conosco altro modo, e questo metodo sarà legato a un compito specifico

e l'autore vuole una soluzione universale per 10 sterline, beh, aspettiamo e vediamo se qualcosa si chiarisce

 
Maxim Kuznetsov:

Perché ordinare l'array/vettore di strutture spesse in campi diversi?

Lasciatelo così com'è, ha il diritto di essere anche const :-) e per diversi scopi potete costruire degli indici

Qualcuno scriverà ora ... che è così scomodo per me ... che non siamo casalinghe, ma super sviluppatori, e dobbiamo usare tutte le possibilità delle moderne tecnologie di programmazione, mentre un array aggiuntivo è qualcosa come il Medioevo ...

Anche se, personalmente, mi piace di più questa opzione.

#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:

Niente da fare:
1) Basta inserire ArrayCopy nella compilazione condizionale, non ArraySwap.
2) ArrayCopy deve essere scritto in uno personalizzato, poiché quello standard non supporta le strutture NonPod.
3) Abbiamo bisogno di un'altra compilazione condizionale per ArrayResize array multi-dominio (la funzione dà risultati diversi per diverse versioni di MT)

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:

Non lo farà:

La risposta non era per tutte le occasioni. La maggior parte delle persone chiude.

Motivazione: