Функция - Метод сортировки массива структур. Приз 10$ - страница 2

 
Dmitry Fedoseev:

В одном месте тип переменной изменить, а три остальных компилятор ошибками покажет - изменить имя поля. Можно подумать где-то десятки структур требуют сортировки. Да скорее всего одна структура требует сортировки.

нет не так задачу ставьте

а поставьте такую задачу: с помощью Вашего примера отсортировать структуру у которой десятки полей по каждому полю

ну и конкретный пример - пусть будет структура содержащая все свойства ордера "четверки" (OrderStoploss(), OrderTakeProfit(), OrderOpenTime()....) - их там с десяток то и наберется

и воспроизведите своим примеров сортировку массива таких структур по каждому полю ? - имхо, код Ваш довольно прилично будет весить, про то, что повторно такой код не возможно будет использовать выше писал

 
Igor Makanu:

нет не так задачу ставьте

а поставьте такую задачу: с помощью Вашего примера отсортировать структуру у которой десятки полей по каждому полю

ну и конкретный пример - пусть будет структура содержащая все свойства ордера "четверки" (OrderStoploss(), OrderTakeProfit(), OrderOpenTime()....) - их там с десяток то и наберется

и воспроизведите своим примеров сортировку массива таких структур по каждому полю ? - имхо, код Ваш довольно прилично будет весить, про то, что повторно такой код не возможно будет использовать выше писал

Задача из области фантастики, ни разу не встречавшаяся практически. 

Можно сделать отдельное поле по которому сортировать и перед сортировкой в него копировать с того поля, по которому надо сделать сортировку.

 
Vladimir Pastushak:

В MT 5 работает без проблем в МТ 4 ругается на ArraySwap   так как Mql 4 ее не поддерживает...

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

Задача из области фантастики.

да нет, возможно средствами MQL, как раз, как Вы и предлагали использую СБ

но проблема будет, что этот код будет написан под конкретную задачу

ну если в примерах - воспроизвели панель терминала с ордерами в виде окошка MQL, сделали сортировки, все крутится, все работает

а захотели использовать часть кода для воспроизведения панели тестера "оптимизация", и получите, что правки вагон с тележкой, проще опять, по сути с нуля писать код, включая сортировки, имена полей же структур захочется иметь в удобочитаемом виде? - иначе нужно быть автором известного "ядра", чтобы держать в голове все имена идентификаторов в виде Абырвалг (Собачье сердце)

)))

 
Igor Makanu:

да нет, возможно средствами MQL, как раз, как Вы и предлагали использую СБ

но проблема будет, что этот код будет написан под конкретную задачу

ну если в примерах - воспроизвели панель терминала с ордерами в виде окошка MQL, сделали сортировки, все крутится, все работает

а захотели использовать часть кода для воспроизведения панели тестера "оптимизация", и получите, что правки вагон с тележкой, проще опять, по сути с нуля писать код, включая сортировки, имена полей же структур захочется иметь в удобочитаемом виде? - иначе нужно быть автором известного "ядра", чтобы держать в голове все имена идентификаторов в виде Абырвалг (Собачье сердце)

)))

Все, что может быть понято не так, будет понято не так. Имел виду не возможность/невозможность, а практическую потребность в этом, то есть встречаемость этой задачи.

Не я придумал, что для каждой структуры надо писать свою Compare().

 

а зачем сортировать массив/вектор толстых структур по разным полям ?

пусть он лежит как есть, он имеет право быть даже const  :-) а для разных целей можно строить индексы

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

Не я придумал, что для каждой структуры надо писать свою Compare().

именно так и есть, вернее я не знаю другого способа, а этот способ будет привязан к конкретной задаче

а топикстартер хочет за 10 баксов универсальное решение, ну как бы подождем, а вдруг что то и прояснится

 
Maxim Kuznetsov:

а зачем сортировать массив/вектор толстых структур по разным полям ?

пусть он лежит как есть, он имеет право быть даже const  :-) а для разных целей можно строить индексы

Сейчас кто-нибудь напишет... что мне так неудобно... что мы не домохозяйки, а супердевёлоперы и должны пользоваться всеми возможностями современных программистских технолгий, а дополнительный массив, это какое-то средневековье...

Хотя лично мне как раз такой вариант больше нравится.

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

Не прокатит:
1) Достаточно ArrayCopy в условную компиляцию вставить а не ArraySwap.
2) ArrayCopy необходимо прописывать кастомную, так как стандартная не поддерживает NonPod структуры.
3) Нужно еще одну условную компиляцию для ArrayResize многодоменного массива (функция дает разные результаты для разных версий МТ)

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:

Не прокатит:

Ответ был не на все случаи жизни. Большинство закрывает.

Причина обращения: