2012-03-01 2 views
0

У меня проблема.Сортировка объектов в ArrayList по переменной DateTime внутри объектов

У меня есть ArrayList объектов. Каждый объект содержит поле данных DateTime.

Мне нужно разобрать ArrayList этим DateTime поле данных.

Это мой текущий код и он не работает:

 for (int i = 0;i<EventHolder.Count;i++) 
     { 
      Event obj = (Event) EventHolder[i]; 
      try 
      { 
       obj2=(Event)EventHolder[i+1]; 
      } 
      catch 
      { 
       break; 
      } 
      DateTime date1 = DateTime.ParseExact(obj.Date_And_Time,"dd/MM/yyyy HH:mm",region); 
      DateTime date2 = DateTime.ParseExact(obj2.Date_And_Time, "dd/MM/yyyy HH:mm", region); 
      if (DateTime.Compare(date1,date2)>0) 
      { 
       Event tempobj=obj2; 
       EventHolder[i+1]=obj; 
       EventHolder[i]=tempobj; 
      } 
     } 
     foreach (Event i in EventHolder) 
     { 
      Console.WriteLine(i.Date_And_Time); 
     } 
     Console.ReadLine(); 

Я использую эти 3 даты, чтобы проверить, работает ли он:

23/11/2011 12:15

28/06/2010 04:05

02/09/1992 03:54

Выход всегда:

28/06/2010 04:05

02/09/1992 03:54

23/11/2011 12:15

Я попытался использовать только> и < операторов для сравнения и получил те же результаты. Я также попытался использовать разные команды для преобразования строк в объекты DateTime, например Convert.ToDateTime, DateTime.Parse. Пробовал вводить без ЧЧ: мм (скорректировал код соответственно) и все равно имел тот же результат. Я попробовал не использовать IFormatProvider (установить его значение null) и больше не получил ничего.

Случайно, я нашел эту тему:

How to sort ArrayList of DateTime objects in descending order?

я извлеченный все даты из объектов и поместить их в этот список DateTime. Использовал List.Sort() и произвел правильный выход. Но затем я застрял в том, как использовать этот отсортированный список для сортировки моего EventHolder ArrayList. Некоторое время я стучал в эту стену и ничего не добился.

Я очень новичок в программировании, поэтому я почти не знаю, как хорошо делать то, что я делаю. И это даже не работает. Может кто-нибудь объяснить мне, где я ошибаюсь?

+0

Вам нужно придерживаться старого и уродливого ArrayList? Если вы использовали общие коллекции и LINQ, вся эта задача могла быть выполнена в 1 строке кода. –

+0

Может использовать List вместо этого, не обязательно быть администратором. – eltaro

+0

Я бы рекомендовал не использовать LINQ для чего-то подобного. Вы можете получить только одну строку кода, но она будет значительно медленнее, чем просто использование 'ArrayList.Sort()' или 'List .Sort()'. – xxbbcc

ответ

0

Что вы пытаетесь сделать, существует реализация алгоритма сортировки, но, к сожалению, ваш не является правильным. Он почти похож на Bubble Sort, и это довольно медленный алгоритм, но это не совсем правильно.

Лучше всего выполнить то, что вы пытаетесь сделать, это использовать метод Sort или ArrayList или общий список классов <. Эти методы сортировки позволяют вам предоставить реализацию IComparer (или делегат сравнения в случае общего списка), чтобы указать критерии сортировки, и внутренне они используют правильный и эффективный алгоритм сортировки.

Если вы используете общий список <> вы могли бы просто передать лямбда-выражения и он диктует критерии сортировки на основе поля даты, например, так:

// Assuming EventHolder is a List<Event> 
EventHolder.Sort((d1, d2) => DateTime.ParseExact(d1.Date_And_Time,"dd/MM/yyyy HH:mm",region).CompareTo(DateTime.ParseExact(d2.Date_And_Time,"dd/MM/yyyy HH:mm",region))); 
+0

Что такое выражение лямбда? Я пробовал этот код, он выдает ошибку, Невозможно преобразовать выражение лямбда для ввода: 'System.Collections.Generic.IComparer , потому что это не тип делегата. – eltaro

+0

В этом поле комментариев недостаточно места, чтобы объяснить, что такое лямбда-выражение, поэтому я просто попытаюсь дать вам представление, как оно применяется в вашем случае: подумайте об этом как анонимную функцию, объявленную в строке, которая интерпретируется компилятором в качестве делегата. В моем примере выражение лямбда есть (d1, d2) => ... Это похоже на объявление функции, которая принимает в этом случае два параметра d1 и d2 типа Event, а затем возвращает (=>) результат вычисления с использованием два параметра. Подробнее см. На странице MSDN на лямбда-выражениях здесь: http://msdn.microsoft.com/en-us/library/3da4abas.aspx –

+0

Я преобразовал EventHolder в список и добавил ваш код. Это еще раз дает мне ошибку. Добавление с использованием System.Linq; тоже не помогло. – eltaro

0

Использование this перегрузка ArrayList.Sort() - вы получите обратный вызов для каждого сравнения с вашими объектами, и вы можете легко сравнить две даты внутри ваших объектов.

public class MyDateComparer : IComparer 
{ 
    int IComparer.Compare (Object x, Object y) 
    { 
     // Cast x and y to your object type and then compare the dates. Return 
     // -1, 0 or 1 depending on your comparison 
     return (...); 
    } 
} 

... 

myList.Sort (0, myList.Length, new MyDateComparer()); 
0

Это неправильный подход имо, лучший способ сделать это состоит в использовании Custom comparer.

public class SortByDateTime: IComparer { 
     // Calls CaseInsensitiveComparer.Compare with the parameters reversed. 
     int IComparer.Compare(Object x, Object y) { 
      // Compare objects according to the date 
      } 
     } 

    ... 
    // Sort the arraylist using the custom comparer 
    IComparer myComparer = new SortByDateTime(); 
    ArrayList mList = new ArrayList(); 
    mList.Sort(myComparer); 
+0

Я не думаю, что ArrayList является общим типом. Вы можете исправить свой пример. – xxbbcc

+0

@xxbbcc примечание – Shai

+0

благодарим за ваши быстрые ответы. Я сейчас пытаюсь понять этот фрагмент кода и адаптировать его к своей программе. – eltaro

0

Если вы на самом деле не нужны ArrayList и .NET 3.5 попробуйте вместо этого:

List<Event> eventHolder = ... // Just to make certain it's a List<Event> 
eventHolder = eventHolder 
    .OrderBy(e => DateTime.ParseExact(e.Date_And_Time,"dd/MM/yyyy HH:mm",region) 
    .ToList(); 
Смежные вопросы