2

I am not sure how to go about sorting the ArrayList which contains an object Array which has a DateTime object and a String object. I am ultimately trying to sort the ArrayList based on the first object (DateTime) of the array within the ArrayList.

I've tried to search around for sorting but articles didn't seem to go into the level of detail or this particular use-case the application is hitting. I'm not sure if this is the best way to deal with the data either but any help suggestion will certainly be appreciative.

The goal is to read mutliple XML files and combine all the Lap data out of the all the XML files and sort them from oldest to most recent then to create a new XML file with the combined sorted information in it.

ArrayList LapsArrayList = new ArrayList();
ListBox.SelectedObjectCollection SelectedItems = lstSelectedFiles.SelectedItems;
foreach (string Selected in SelectedItems)
{
 Object[] LapArray = new Object[2];
 XmlDocument xDoc = new XmlDocument();
 xDoc.Load(Path + @"\" + Selected);
 XmlNodeList Laps = xDoc.GetElementsByTagName("Lap");
 foreach (XmlElement Lap in Laps)
 {
 LapArray[0] = DateTime.Parse(Lap.Attributes[0].Value);
 LapArray[1] = Lap.InnerXml.ToString();
 LapsArrayList.Add(LapArray);
 }
}

XML Data Example

<Lap StartTime="2013-06-17T12:27:21Z"><TotalTimeSeconds>12705.21</TotalTimeSeconds><DistanceMeters>91735.562500</DistanceMeters><MaximumSpeed>10.839000</MaximumSpeed><Calories>3135</Calories><AverageHeartRateBpm><Value>151</Value>.....</Lap>
asked Jun 25, 2013 at 3:48
2
  • 3
    You should be using generic List<T> instead of ArrayList. Commented Jun 25, 2013 at 3:51
  • If you use a class for your pair of DateTime and String (or say a tuple) then you have the more common case where you sort objects by a property. Commented Jun 25, 2013 at 3:51

1 Answer 1

5

This are my recommendations:

  1. Use a class for the items you want to sort, I suggest a Tuple<T1, T2>.
  2. Use a List<T> because it is a typed list so you avoid casts and it is more convenient in general.
  3. We are going to use Linq to sort the array just for easy writting.

I list the code below:

//I dunno what does this has to do, but I'll leave it here
ListBox.SelectedObjectCollection SelectedItems = lstSelectedFiles.SelectedItems;
//We are going to use a List<T> instead of ArrayList
//also we are going to use Tuple<DateTime, String> for the items
var LapsList = new List<Tuple<DateTime, String>>();
foreach (string Selected in SelectedItems)
{
 XmlDocument xDoc = new XmlDocument();
 xDoc.Load(Path + @"\" + Selected);
 XmlNodeList Laps = xDoc.GetElementsByTagName("Lap");
 foreach (XmlElement Lap in Laps)
 {
 var dateTime = DateTime.Parse(Lap.Attributes[0].Value);
 var str = Lap.InnerXml.ToString();
 //Here we create the tuple and add it
 LapsList.Add(new Tuple<DateTime, String>(dateTime, str));
 }
}
//We are sorting with Linq
LapsList = LapsList.OrderBy(lap => lap.Item1).ToList();

If you can't use tuples, declare you own class for the item. For example

class Lap
{
 private DateTime _dateTime;
 private String _string;
 public Lap (DateTime dateTimeValue, String stringValue)
 {
 _dateTime = dateTimeValue;
 _string = stringValue;
 }
 public DateTime DateTimeValue
 {
 get
 {
 return _dateTime;
 }
 set
 {
 _dateTime = value;
 }
 }
 public String StringValue
 {
 get
 {
 return _string;
 }
 set
 {
 _string = value;
 }
 }
}

With this class you can do a easy migration of the code as follows:

//I dunno what does this has to do, but I'll leave it here
ListBox.SelectedObjectCollection SelectedItems = lstSelectedFiles.SelectedItems;
//We are going to use a List<T> instead of ArrayList
//also we are going to use the Laps class for the items
var LapsList = new List<Lap>();
foreach (string Selected in SelectedItems)
{
 XmlDocument xDoc = new XmlDocument();
 xDoc.Load(Path + @"\" + Selected);
 XmlNodeList Laps = xDoc.GetElementsByTagName("Lap");
 foreach (XmlElement Lap in Laps)
 {
 var dateTime = DateTime.Parse(Lap.Attributes[0].Value);
 var str = Lap.InnerXml.ToString();
 //Here we create the Lap object and add it
 LapsList.Add(new Lap(dateTime, str));
 }
}
//We are sorting with Linq
LapsList = LapsList.OrderBy(lap => lap.DateTimeValue).ToList();

If you can't use Linq, here is a non Linq alternative:

LapsList.Sort
(
 delegate(Tuple<DateTime, String> p1, Tuple<DateTime, String> p2)
 {
 return p1.Item1.CompareTo(p2.Item1);
 }
);

Or for the case of using the Lap class:

LapsList.Sort
(
 delegate(Lap p1, Lap p2)
 {
 return p1.DateTimeValue.CompareTo(p2.DateTimeValue);
 }
);
answered Jun 25, 2013 at 4:01

4 Comments

I'd love to upvote twice for both the LINQ and non-LINQ solutions, as well as use of the Tuple. Well done.
I personally suggest you deserialize the XML to a Lap class. Secondly I would use a BindingList<> or ObservableCollection<> since it looks like you are writing UI code.
I never even knew about Tuple or how to use it. I am still learning more advanced concepts and this greatly helps. Excellent write-up and super quick response! Kudos! Aron, you are correct. I will certainly take your suggestions and do some research more to understand why that would be a benefit. Do you have some resources you can shoot my way to help? Thanks!
@tkrn I'm glad it helps you. This web site is good to give developer practice in reading and writing for humans intead of machines :P About the ObjservableCollection I can susggest you this article at CodeProject that underlines the base concept: codeproject.com/Articles/42536/… and don't miss msdn: msdn.microsoft.com/en-us/library/ms668604.aspx Sadly I don't have something more advanced at hand.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.