简体   繁体   中英

Sorting List<List<MyType>>

I have 2D a list of "NameValuePair"s that I've been trying to order with no luck so far.

NameValuePair is defined as:

public class NameValuePair
    {
        [DataMember]
        public string Name { get; set; }
        [DataMember]
        public string Value { get; set; }
    }

The list is defined as:

List<List<NameValuePair>> outerList = new List<List<NameValuePair>>();

Each list in outer list might have different number of items at different indices but each one has a "Date" item for sure.

eg

List<List<NameValuePair>> outerList = new List<List<NameValuePair>>();
List<NameValuePair> innerList = new List<NameValuePair>();
List<NameValuePair> innerList2 = new List<NameValuePair>();


innerList.Add(new NameValuePair { Name = "List1Item1", Value = "someValue" });
innerList.Add(new NameValuePair { Name = "List1Item2", Value = "otherValue" });
innerList.Add(new NameValuePair { Name = "List1ItemN", Value = "anotherValue" });
innerList.Add(new NameValuePair { Name = "Date", Value = "aDateInStringFormat" });
innerList2.Add(new NameValuePair { Name = "List2Item1", Value = "myValue" });
innerList2.Add(new NameValuePair { Name = "Date", Value = "anotherDateInStringFormat" });
innerList2.Add(new NameValuePair { Name = "List2ItemM", Value = "bestValue" });

outerList.Add(innerList);
outerList.Add(innerList2);

I have tried sorting with outerList.Sort(); and outerList.OrderByDescending(x => x.Where(y => y.Name == "Date")).ToList(); with no luck so far.

I also tried implementing IComparable to my NameValuePair type by overloading CompareTo() but couldn't get it working either.

Any suggestions are more than welcome.

Assuming each inner list has exactly one item with name Date and a proper formated date Value :

var sorted = outerList.OrderBy(x => DateTime.Parse(x.Single(y => y.Name == "Date").Value))
                      .ToList();

The Linq query takes the NameValuePair with the Name "Date", converts the Value to a DateTime object and sorts the outer list by this value.

Anyway you should think about creating a class with a DateTime property instead.

I know this has already been answered, but here's a slightly different take which is likely to be more performant.

Firstly, do a single pass of all the lists to extract the date times into a separate sequence:

var keys = outerList.Select(x => DateTime.Parse(x.Single(y => y.Name == "Date").Value));

Then use Zip and that DateTime sequence to sort the outer list by that sequence:

outerList = outerList.Zip(keys, (pairs, date) => new {Pairs = pairs, Date = date})
    .OrderByDescending(item => item.Date)
    .Select(item => item.Pairs)
    .ToList();

This avoid multiple calls to IEnumerable.Single() and DateTime parsing whenever two elements are compared during the sorting.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM