2015-04-17 4 views
0

у меня есть этот класс в своем кодеСортировка списка объектов нескольких типов данных

class Stock 
{ 
    public DateTime Date; 
    public string Day; 
    public double Open, Close, Diff; 
    public int Volume; 

    public Stock(double open, double close, double diff, int volume, string day, DateTime date) 
    { 
     this.Open = open; 
     this.Close = close; 
     this.Diff = diff; 
     this.Volume = volume; 
     this.Day = day; 
     this.Date = date; 
    } 
} 

В другом классе я хочу, чтобы создать пузырь сортировки, который будет сортировать список акций (List<Stocks>) перешел к нему, У меня есть несколько проблем с этой проблемой, основная проблема связана с типами данных, а это не просто сравнение двух значений, когда они могут быть string, int, double или DateTime. Я сделал это с помощью метода, который использует TryParse для проверки действительного типа данных, но им ищет хороший чистый раствор, это моя попытка до сих пор

public void BubblesortBy(int sortBy, List<Stock> Stocks) 
{ 

    Type objType = typeof(Stock); 
    FieldInfo[] fields = objType.GetFields(); 

    Stock temp = null; 
    int loopCount = 0; 
    bool doBreak = true; 

    for (int i = 0; i < Stocks.Count; i++) 
    { 
     doBreak = true; 
     for (int j = 0; j < Stocks.Count - 1; j++) 
     { 
      if (Compare(fields[sortBy - 1].FieldType.ToString(), fields[sortBy].GetValue(Stocks[j]), fields[sortBy].GetValue(Stocks[j+1]))) 
      { 
       temp = Stocks[sortBy + 1]; 
       Stocks[sortBy + 1] = Stocks[sortBy]; 
       Stocks[sortBy] = temp; 
       doBreak = false; 
      } 
      loopCount++; 
     } 
     if (doBreak) { break; /*early escape*/ } 
    } 
} 

int переданный ей определяет, следует ли сортировать, поэтому я использую отражение, поэтому переменные доступны по номерам.

  1. Дата
  2. День
  3. Открыть
  4. Закрыть
  5. Разница
  6. Объем
+0

Я бы рекомендовал использовать оператор switch и выполнять сравнения на основе типа данных в ваших блоках case. –

+2

Вы внедряете сортировку пузыря в качестве учебного упражнения или для практических целей? Для 99,9% практических целей не реализуйте свой собственный алгоритм сортировки. –

+0

@TimS. Как узнать, как эффективно проверять типы данных? –

ответ

1

Вы не должны считать, что поля возвращается GetFields будет в определенном порядке.

Метод GetFields не возвращает поля в определенном порядке, например, в алфавитном порядке или в указании. Ваш код не должен зависеть от порядка, в котором возвращаются поля, поскольку этот порядок варьируется.

Один из вариантов заключается в использовании lambdas, как LINQ's OrderBy способ. Использование универсальных типов также может сделать ваш код более многоразовым, и сделать вещи, как ваш Compare метод проще.

public void BubblesortBy<TSource, TKey>(Func<TSource, TKey> keySelector, 
             List<TSource> stocks) 
{ 
    int loopCount = 0; 
    bool doBreak = true; 

    for (int i = 0; i < stocks.Count; i++) 
    { 
     doBreak = true; 
     for (int j = 0; j < stocks.Count - 1; j++) 
     { 
      if (Compare(keySelector(stocks[j]), keySelector(stocks[j+1]))) 
      { 
       TSource temp = stocks[j + 1]; 
       stocks[j + 1] = stocks[j]; 
       stocks[j] = temp; 
       doBreak = false; 
      } 
      loopCount++; 
     } 
     if (doBreak) { break; /*early escape*/ } 
    } 
} 
private bool Compare<T>(T l, T r) 
{ 
    return Comparer<T>.Default.Compare(l, r) > 0; 
} 

// use like 
BubblesortBy(x => x.Close, myList); 
+0

Спасибо @Tim S. за этот ответ, как бы я это назвал, поскольку я получаю ошибку «Аргументы типа для метода» Stocks.Program .Sort.BubblesortBy (System.Func , System.Collections.Generic.List ) 'не может быть выведен из использования. Попробуйте указать аргументы типа явно "с помощью Sort.BubblesortBy (secondNumber, Запасы); –

+1

@ Раймонд Я добавил пример сейчас. Используйте lambda как 'x => x.Volume' вместо' int', чтобы указать, какое поле использовать для сравнения. –

+0

Этот ответ именно то, что я искал, для понимания того, как работает Func keySelector? я никогда не работал с функциями IComparable до –

1

Почему ты осуществляет сортировку себя? Посмотрите в IComparable

Edit:

Приятный и тип безопасный способ передать поле для сортировки по методу в без трапезу, было бы:

BubblesortBy(x => x.FieldName, stockes); 

public void BubblesortBy<T>(Func<Product, T> sortBy, List<Stock> Stocks) 
{ 
    Stock temp = null; 
    int loopCount = 0; 
    bool doBreak = true; 

    for (int i = 0; i < Stocks.Count; i++) 
    { 
     doBreak = true; 
     for (int j = 0; j < Stocks.Count - 1; j++) 
     { 
      if (Compare(sortBy(Stocks[j]), sortBy(Stocks[j + 1]))) 
      { 
       temp = Stocks[sortBy + 1]; 
       Stocks[sortBy + 1] = Stocks[sortBy]; 
       Stocks[sortBy] = temp; 
       doBreak = false; 
      } 
      loopCount++; 
     } 
     if (doBreak) 
      break; /*early escape*/ 
    } 
} 
+0

Извините, я должен объяснить, это для обучения –

+1

@ RaymondTunstill добавил образец к моему сообщению –

Смежные вопросы