2014-01-24 32 views
1

我正在从电子表格创建计算到C#中,我想知道C#是否有类似Excel的排名方法?C#中的VBA/Excel排名#

排名在Excel

返回号码列表中的号码军衔。 号码的排名是其相对于列表中其他值的大小。 (如果你要 列表排序,数量的排名将是它的位置。)

语法

RANK(数量,REF顺序)

是多少你想要找到你的等级。

参考号是数组列表或数字列表的引用。 忽略ref中的非数值。

订购是一个数字,指定如何排名数字。

如果订单为0(零)或省略,Microsoft Excel会将编号排序,就好像 ref是按降序排列的列表。如果订单的值为非零值 ,则Microsoft Excel将按照 的升序顺序排列号码,就像ref是一个列表。

同样可以通过代码来实现,但我只是想检查是否有什么我首先失踪。

回答

3

你可以,有点。

 SortedList<int, object> list = new SortedList<int, object>(); 
     // fill with unique ints, and then look for one 
     int rank = list.Keys.IndexOf(i); 

排名将是递增的,从零开始的位置。

你可以漂亮起来写一个扩展方法:

public static class Extensions 
{ 
    public static int Rank(this int[] array, int find) 
    { 
     SortedList<int, object> list = new SortedList<int, object>(); 
     for (int i = 0; i < array.Length; i++) 
     { 
      list.Add(array[i], null); 
     } 
     if (list.ContainsKey(find)) 
     { 
      return list.Keys.IndexOf(find); 
     } 
     else 
     { 
      return -1; 
     } 
    } 
} 

而且使用它像:

int[] ints = new int[] { 2, 7, 6, 3, 9, 12 }; 
    int rank = ints.Rank(2); 

...但我不认为它是最明智的做法。

+0

感谢您的建议。我最终做了与此类似的事情,我很快就会发布我的版本。 – christiandev

1

要获得RANK相当于你需要得到每个项目的最低指标,当你组:

var ranks = list.OrderBy(x => x) 
       .Select((x, i) => new {x, i = i+1}) // get 1-based index of each item 
       .GroupBy(xi => xi.x)  // group by the item 
       .Select(g => new {rank = g.Min(xi => xi.i), items = g}) // rank = min index of group 
       .SelectMany(g => g.items, (g, gg) => new {g.rank, gg.i}) ; // select rank and item 

,或者如果you'rs一类的属性分组:

var ranks = list.OrderBy(x => x.{some property}) 
       .Select((x, i) => new {x, i = i+1}) // get 1-based index of each item 
       .GroupBy(xi => xi.x.{some property})  // group by the item's property 
       .Select(g => new {rank = g.Min(xi => xi.i), items = g}) // rank = min index of group 
       .SelectMany(g => g.items, (g, gg) => new {g.rank, gg.i}) ; // select rank and item 
+0

我使用类似于@Simon的解决方案来满足我的测试,我也会看看这个解决方案,并更新一次测试。谢谢。 – christiandev

0

这个工作对我来说,到目前为止(和更简单)

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

我用T因此它可以采取所有数字类型(int/double/decimal)。

用法相似到Excel

int[] data = new[] { 3, 2, 2, 3, 4 }; 
int rank = Rank(3, data); // returns 2 

我希望我没有错过任何东西