This is pretty ugly, but works for me using this class of patterns.
public class Participant { public int Id { get; set; } public int Score1 { get; set; } public int Score2 { get; set; } public int ExpectedRank { get; set; } }
In this collection:
var participants = new Participant[] { new Participant { Id = 1, Score1 = 2, Score2 = 5, ExpectedRank = 6 }, new Participant { Id = 2, Score1 = 10, Score2 = 8, ExpectedRank = 1 }, new Participant { Id = 3, Score1 = 7, Score2 = 2, ExpectedRank = 4 }, new Participant { Id = 4, Score1 = 7, Score2 = 4, ExpectedRank = 3 }, new Participant { Id = 5, Score1 = 7, Score2 = 2, ExpectedRank = 4 }, new Participant { Id = 6, Score1 = 7, Score2 = 7, ExpectedRank = 2 }, };
By executing the following pretty ugly LINQ query:
var ranked = participants .OrderByDescending(p => p.Score1) .ThenByDescending(p => p.Score2) .Select((p, i) => new { Order = 1 + i, Participant = p }) .GroupBy(p => new { p.Participant.Score1, p.Participant.Score2 }) .SelectMany(g => g.Select(p => new { Id = p.Participant.Id, Rank = g.Min(x => x.Order), ExpectedRank = p.Participant.ExpectedRank })); foreach (var p in ranked) Console.WriteLine(p);
Which produces the following output:
{ Id = 2, Rank = 1, ExpectedRank = 1 } { Id = 6, Rank = 2, ExpectedRank = 2 } { Id = 4, Rank = 3, ExpectedRank = 3 } { Id = 3, Rank = 4, ExpectedRank = 4 } { Id = 5, Rank = 4, ExpectedRank = 4 } { Id = 1, Rank = 6, ExpectedRank = 6 }