按对象内部的DateTime变量对ArrayList中的对象进行排序

本文关键字:对象 ArrayList 排序 变量 内部 DateTime | 更新日期: 2023-09-27 18:26:11

我有个问题。

我有一个对象的ArrayList。每个对象都包含一个DateTime数据字段。

我需要根据这个DateTime数据字段对这个ArrayList进行排序。

这是我当前的代码,它不起作用:

        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个日期来测试它是否有效:

2011年11月23日下午12:15

2010年6月28日04:05

1992年9月2日03:54

输出始终为:

2010年6月28日04:05

1992年9月2日03:54

2011年11月23日下午12:15

我试着只使用>和<运算符进行比较,得到了相同的结果。我还尝试使用不同的命令将字符串转换为DateTime对象,如Convert.ToDateTimeDateTime.Parse。尝试在没有HH:mm的情况下输入(相应地调整了代码),但仍然有相同的输出。我尝试不使用IFormatProvider(将其设置为null),但再次一无所获。

一次偶然的机会,我发现了这个线索:

如何按降序对DateTime对象的ArrayList进行排序?

我从对象中提取了所有日期,并将它们放入DateTime列表中。使用List.Sort(),它产生了正确的输出。但后来我陷入了如何使用这个排序列表对EventHolder ArrayList进行排序的困境。我已经在这堵墙上敲了一段时间,但没有产生任何结果。

我对编程很陌生,所以我几乎不知道有什么好方法可以做我正在做的事情。它甚至不起作用。有人能向我解释一下我哪里错了吗?

按对象内部的DateTime变量对ArrayList中的对象进行排序

您要做的是实现一个排序算法,但不幸的是,您的算法不正确。它看起来几乎像Bubble Sort,这是一个非常慢的算法,但它并不完全正确。

实现您想要做的事情的更好方法是使用Sort方法或ArrayList或泛型List<>类。这些排序方法允许您提供一个IComparer实现(或者在泛型List的情况下提供一个比较委托)来指定排序条件,并且在内部使用正确有效的排序算法。

如果使用通用列表<>您可以只传入一个lambda表达式,并让它根据日期字段指定排序条件,如下所示:

// 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)));

使用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 () );

这是一种错误的方法,更好的方法是使用自定义比较器。

   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);

如果您并不真的需要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();