Reputation:
I am trying to figure out a way to rank items in a list, and hold the results in an object or another list. I know about the orderby method, but I don't exactly know how to go about creating a corresponding rank number for each item.
For example:
List<int> numbers = new List<int>();
numbers.Add(650);
numbers.Add(150);
numbers.Add(500);
numbers.Add(200);
and then store the results from either low to high or high to low here:
public class NumberRank
{
public int Number {get; set;}
public int Rank {get; set;}
public NumberRank(int number)
{
Number = number;
Rank = ????????;
}
}
Any solutions through LINQ?
Upvotes: 8
Views: 15950
Reputation: 6368
Function Rank(Of T As IComparable)(list As IEnumerable(Of T), item As T) As Integer
Return list.Count(Function(x) x.CompareTo(item) < 0) + 1
End Function
Public Sub Main()
Dim l = New Integer() {9, 1, 3, 8, 4, 6}
Console.WriteLine("6 is the " & Rank(l,6) & "th element of ")
Console.WriteLine([String].Join(" ", l))
End Sub
6 is the 4th element of
9 1 3 8 4 6
Or, in C# http://dotnetfiddle.net/3ZGeJ1
Upvotes: 1
Reputation: 17058
One of the overload of the Select extension method return the index:
Projects each element of a sequence into a new form by incorporating the element's index.
You can use it to make your rank:
public class NumberRank
{
public int Number {get; set;}
public int Rank {get; set;}
public NumberRank(int number, int rank)
{
Number = number;
Rank = rank;
}
}
List<int> numbers = new List();
numbers.Add(650);
numbers.Add(150);
numbers.Add(500);
numbers.Add(200);
numbers.OrderBy(n => n)
.Select((n, index) => new NumberRank(n, index));
Upvotes: 18
Reputation: 3046
This should do it:
public class NumberRank
{
public int Number {get; set;}
public int Rank {get; set;}
public NumberRank(int number, int rank)
{
Number = number;
Rank = rank;
}
}
class Test
{
static void Main()
{
List<int> numbers = new List<int>();
numbers.Add(650);
numbers.Add(150);
numbers.Add(500);
numbers.Add(200);
List<NumberRank> numberRanks = numbers.OrderByDescending(n => n).Select((n, i) => new NumberRank(n, i + 1)).ToList();
// check it worked
foreach(NumberRank nr in numberRanks) Console.WriteLine("{0} : {1}", nr.Rank, nr.Number);
Console.ReadKey();
}
}
To rank in ascending order (i.e. lowest number first), then just replace OrderByDescending by OrderBy.
Upvotes: 12