Home > Enterprise >  Linq ordering by multiple values
Linq ordering by multiple values

Time:09-17

I currently have a list of persons that I would like to sort on the TimeSpans in the list. My class looks as below:

public class PersonClass
{
   public string name { get; set; }
   public TimeSpan Time { get; set; }
   public TimeSpan OfficialTime { get; set; }
}

So I would like to sort on the two columns at once and display the lowest time across the two columns but only if a value was actually present, and giving more weight to the OfficialTime

So to give a few examples

Person1; Time:00:03:02; OfficialTime:00:03:01
Person2; Time:00:02:54; OfficialTime:00:02:55
Person3; Time:00:02:56; OfficialTime:00:00:00
Person4; Time:00:00:00; OfficialTime:00:00:00
Person5; Time:00:00:00; OfficialTime:00:02:57
Person6; Time:00:01:16; OfficialTime:00:02:58

So to sort I need to sort on the OfficialTime where it is available and higher than 0. If there are Persons that have a Time but not an OfficialTime, then I would like to use the Time in the Sort. When both Time and OfficialTime are 0, they should not be added to the tmpList.

So in the above example the order would be:

Person2; Time:00:02:54; OfficialTime:00:02:55
Person3; Time:00:02:56; OfficialTime:00:00:00
Person5; Time:00:00:00; OfficialTime:00:02:57
Person6; Time:00:01:16; OfficialTime:00:02:58
Person1; Time:00:03:02; OfficialTime:00:03:01

So I tried using the following code:

var tmpList = Persons.OrderBy(x => x.OfficialTime)
                    .ThenBy(x => x.Time)
                    .Where(x => x.OfficialTime > TimeSpan.FromSeconds(0) || x.Time > TimeSpan.FromSeconds(0))
                    .ToList();

So what would the correct approach be for this?

For your reference:

private void test()
{
   List<PersonClass> Persons = new List<PersonClass>();
   Persons.Add(new PersonClass() { name = "Person 1", Time = TimeSpan.Parse("00:03:02"), OfficialTime = TimeSpan.Parse("00:03:01") });
   Persons.Add(new PersonClass() { name = "Person 2", Time = TimeSpan.Parse("00:02:54"), OfficialTime = TimeSpan.Parse("00:02:55") });
   Persons.Add(new PersonClass() { name = "Person 3", Time = TimeSpan.Parse("00:02:56"), OfficialTime = TimeSpan.Parse("00:00:00") });
   Persons.Add(new PersonClass() { name = "Person 4", Time = TimeSpan.Parse("00:00:00"), OfficialTime = TimeSpan.Parse("00:00:00") });
   Persons.Add(new PersonClass() { name = "Person 5", Time = TimeSpan.Parse("00:00:00"), OfficialTime = TimeSpan.Parse("00:02:57") });
   Persons.Add(new PersonClass() { name = "Person 6", Time = TimeSpan.Parse("00:01:16"), OfficialTime = TimeSpan.Parse("00:02:58") });
    
   var tmpList = Persons.OrderBy(x => x.OfficialTime)
                        .ThenBy(x => x.Time)
                        .Where(x => x.OfficialTime > TimeSpan.FromSeconds(0) || x.Time > TimeSpan.FromSeconds(0))
                        .ToList();
}

Thanks

CodePudding user response:

Maybe

var results = Persons
   .Where(x => x.OfficialTime > TimeSpan.Zero || x.Time > TimeSpan.Zero)
   .OrderBy(x => x.OfficialTime > x.Time ? x.OfficialTime : x.Time )
   .ToList();

Output

00:02:54 00:02:55
00:02:56 00:00:00
00:00:00 00:02:57
00:01:16 00:02:58
00:03:02 00:03:01
  • Related