tags:

views:

77

answers:

1

Ok, I have a list of lists that I would like to sort. First, some code:

    foreach (var Row in Result)
    {
        foreach (var RowAll in Row.All)
        {
            DataObject.Add(new List<string>() { RowAll.Value1, RowAll.Value2, RowAll.Value3});
            break; 
        }
    }

Now I want to sort the parent list by each child list's Value2. Is this possible? If so, how can I do this?

+6  A: 

You can do this via LINQ:

 // I'm assuming here that "LastCheckin" is defined as List<List<string>> or similar
 // ...

 var sorted = Data.LastCheckin.OrderBy(list => list[1]);

This will return an IEnumerable<List<string>> containing your "lists" sorted by the second value in the sub-list (Value2).


If you want to sort the list in place, you could use List<T>.Sort instead:

 Data.LastCheckin.Sort( (a,b) => a[1].CompareTo(b[1]) );

If you need to specify, at runtime, ascending or decending, an easy way to handle this is:

 bool ascending = true; // Set to false for decending

 int mult = ascending ? 1 : -1;
 Data.LastCheckin.Sort( (a,b) => mult * a[1].CompareTo(b[1]) );

In order to handle more complex checking, you can split your lambda over multiple lines:

 bool ascending = true; // Set to false for decending
 string myDateFormat = GetDateFormat(); // Specify date format

 int mult = ascending ? 1 : -1;
 Data.LastCheckin.Sort( (aStr,bStr) => 
    {
        DateTime a, b;
        bool aSuccess = DateTime.TryParseExact(aStr[1], myDateFormat, DateTimeStyles.None, CultureInfo.InvariantCulture, out a);
        bool bSuccess = DateTime.TryParseExact(bStr[1], myDateFormat, DateTimeStyles.None, CultureInfo.InvariantCulture, out b);

        int result;
        if (!aSuccess)
            result = bSuccess ? -1 : 0;
        else if (!bSuccess)
            result = 1;
        else
            result = a.CompareTo(b);

        return mult * result;

    });

This handles parser failures on a and b, and should put them at the end of the sort.

Reed Copsey
How can I keep the data in Data.LastCheckin without putting it into sorted? Or, how can I access the contents of sorted and put it back into Data.LastCheckin?
Soo
@Soo: I just added an in-place sort that does this via List<T>.Sort. It should do what you're after.
Reed Copsey
How to specify ascending or descending?
Soo
@Soo: Added ascending/descending multiplier for you.
Reed Copsey
@Reed, thanks so much!This bit in my code had bugged me for quite some time.
Soo
@Reed Copsey:The value that I'm sorting is still in string format, so it is sorted in its string format rather than its date format. How can I get this to work so it sorts by the value's date format?
Soo
Reed Copsey
When I use DateTime.Parse, I get an error that reads: String was not recognized as a valid DateTime<br/>This is what my dates look like:<br/>2010-06-26 10:30:00.000
Soo
@Soo: You'll need to use DateTime.ParseExact and supply the format.
Reed Copsey
I'm using: DateTime.ParseExact(b[1], "{0:yyyy-MM-dd HH:mm:ss.fff}", CultureInfo.InvariantCulture) and am getting the same error. I think I'm doing everything correctly
Soo
"yyyy-MM-dd HH:mm:ss.fff" <- I also tried this for the format parameter
Soo
@Soo: The latter should work, given the date you wrote earlier. Can you put the latter, then show the exact string that's failing with it?
Reed Copsey
Ok, it looks like this is failing when there is no date value (this field can be ""). What can I add to skip the parse if it is ""?
Soo
You'll need to put custom logic in there - your "sort" lambda can be multiple lines, so just do a string.IsNullOrEmpty check and return -1/1 appropriately, and that'll put empty entries at the beginning or end.
Reed Copsey
Where would the string.IsNullOrEmpty be in this entire statement? I tried adding an if statement in there and things started to get error-y
Soo
@Soo: I added some code to show you one approach - see my latest edit above.
Reed Copsey
Reed, your code example doesn't work entirely, but I appreciate the effort. I developed a much less elegant solution that I'm using instead. Also, if there is any way I can donate some reputation points to you, I'd like to be able to. Thanks again for all of the help!
Soo
@Soo: No problem. The code i posted above should be close - but I wrote it on the cuff, not using VS - so I couldn't check it. The basic concept should work, fine, however -
Reed Copsey