user3063952
user3063952

Reputation: 97

C# Equivalent Ranking

I'm translating an old Excel system to C#, and I'm having issues with the Rank.eq function. What I did was 3 lists: The list with the original data, the list with the data of the 1st list ordered and the list with the reversed index of the ordered list; then it compares if the list1 value is equal to the list 2 val, it gets the index of the 3rd list in the same position, if not, it skips to the 2nd value to compare, etc.

What I mean, if I have:

1
3
3
5
3
7
9

The ranks shows like this:

No.   Rank
1      5
3      4
3      4
5      3
3      4
7      2
9      1

But what I need is something like this:

    No.   Rank
    1      7
    3      4
    3      4
    5      3
    3      4
    7      2
    9      1

It should skip some numbers if there are repeated values. How can I do the 2nd example? Thanks.

This is my script, in case needed:

int l = 0;
            for (int i = 0; i < dataGridView1.RowCount - 1; )
            {
                if (listBox1.Items[i].ToString() == listBox2.Items[l].ToString())
                {
                    dataGridView1.Rows[i].Cells[4].Value = listBox3.Items[l];
                    i++;
                    l = 0;
                }

                else
                {
                    l++;
                }
            }

Upvotes: 1

Views: 1563

Answers (2)

Aximili
Aximili

Reputation: 29484

My answer on similar question: VBA/Excel RANK in C#

public static int Rank<T>(T value, IEnumerable<T> data)
{
    return data.OrderByDescending(x => x).ToList().IndexOf(value) + 1;
}

Upvotes: 0

Servy
Servy

Reputation: 203830

Here is an implementation of a method that ranks a collection of objects. By grouping the items and then ordering the groups the results can simply be enumerated, keeping track of the number of items yielded up to that point.

public static IEnumerable<Tuple<T, int>> Rank<T>(this IEnumerable<T> source)
{
    var query = source.GroupBy(x => x)
        .OrderByDescending(x => x.Key);

    var rank = 1;
    foreach (var group in query)
    {
        var groupRank = rank;
        foreach (var item in group)
        {
            yield return Tuple.Create(item, groupRank);
            rank++;
        }
    }
}

Upvotes: 3

Related Questions