C# 在我的列表中排列位置的解决方案?

C# 在我的列表中排列位置的解决方案?,c#,.net,linq,list,C#,.net,Linq,List,考虑到以下准则: class Results { public int playerId; public int score; public int section; public int position; public Results(int _playerId, int _score, int _section) { playerId = _playerId; score = _score; s

考虑到以下准则:

class Results
{
    public int playerId;
    public int score;
    public int section;
    public int position;
    public Results(int _playerId, int _score, int _section)
    {
        playerId = _playerId;
        score = _score;
        section = _section;
    }
}

public void RankMyResults()
{
    List<Results> myResultList = new List<Results>();

    myResultList.Add(new Results(1,232, 1));
    myResultList.Add(new Results(2,213, 1));
    // Add a lot of more results

    // Iteriate over the items to set the position
}
在本例中,它将跳过位置2

是否有一种很好的方法可以使用LINQ来实现这一点,或者例如使用列表对象中的一些选择、排序功能


我自己的解决方案迭代列表一点也不好

我几天前刚刚写了这些扩展方法:

    #region RankBy

    public static IEnumerable<TResult> RankBy<TSource, TKey, TResult>(
        this IEnumerable<TSource> source,
        Func<TSource, TKey> keySelector,
        Func<TSource, int, TResult> resultSelector)
    {
        return source.RankBy(keySelector, null, false, resultSelector);
    }

    public static IEnumerable<TResult> RankBy<TSource, TKey, TResult>(
        this IEnumerable<TSource> source,
        Func<TSource, TKey> keySelector,
        IComparer<TKey> comparer,
        Func<TSource, int, TResult> resultSelector)
    {
        return source.RankBy(keySelector, comparer, false, resultSelector);
    }

    public static IEnumerable<TResult> RankByDescending<TSource, TKey, TResult>(
        this IEnumerable<TSource> source,
        Func<TSource, TKey> keySelector,
        IComparer<TKey> comparer,
        Func<TSource, int, TResult> resultSelector)
    {
        return source.RankBy(keySelector, comparer, true, resultSelector);
    }

    public static IEnumerable<TResult> RankByDescending<TSource, TKey, TResult>(
        this IEnumerable<TSource> source,
        Func<TSource, TKey> keySelector,
        Func<TSource, int, TResult> resultSelector)
    {
        return source.RankBy(keySelector, null, true, resultSelector);
    }

    private static IEnumerable<TResult> RankBy<TSource, TKey, TResult>(
        this IEnumerable<TSource> source,
        Func<TSource, TKey> keySelector,
        IComparer<TKey> comparer,
        bool descending,
        Func<TSource, int, TResult> resultSelector)
    {
        comparer = comparer ?? Comparer<TKey>.Default;

        var grouped = source.GroupBy(keySelector);
        var ordered =
            descending
                ? grouped.OrderByDescending(g => g.Key, comparer)
                : grouped.OrderBy(g => g.Key, comparer);

        int totalRank = 1;
        foreach (var group in ordered)
        {
            int rank = totalRank;
            foreach (var item in group)
            {
                yield return resultSelector(item, rank);
                totalRank++;
            }
        }
    }

    #endregion

    #region DenseRankBy

    public static IEnumerable<TResult> DenseRankBy<TSource, TKey, TResult>(
        this IEnumerable<TSource> source,
        Func<TSource, TKey> keySelector,
        Func<TSource, int, TResult> resultSelector)
    {
        return source.DenseRankBy(keySelector, null, false, resultSelector);
    }

    public static IEnumerable<TResult> DenseRankBy<TSource, TKey, TResult>(
        this IEnumerable<TSource> source,
        Func<TSource, TKey> keySelector,
        IComparer<TKey> comparer,
        Func<TSource, int, TResult> resultSelector)
    {
        return source.DenseRankBy(keySelector, comparer, false, resultSelector);
    }

    public static IEnumerable<TResult> DenseRankByDescending<TSource, TKey, TResult>(
        this IEnumerable<TSource> source,
        Func<TSource, TKey> keySelector,
        IComparer<TKey> comparer,
        Func<TSource, int, TResult> resultSelector)
    {
        return source.DenseRankBy(keySelector, comparer, true, resultSelector);
    }

    public static IEnumerable<TResult> DenseRankByDescending<TSource, TKey, TResult>(
        this IEnumerable<TSource> source,
        Func<TSource, TKey> keySelector,
        Func<TSource, int, TResult> resultSelector)
    {
        return source.DenseRankBy(keySelector, null, true, resultSelector);
    }

    private static IEnumerable<TResult> DenseRankBy<TSource, TKey, TResult>(
        this IEnumerable<TSource> source,
        Func<TSource, TKey> keySelector,
        IComparer<TKey> comparer,
        bool descending,
        Func<TSource, int, TResult> resultSelector)
    {
        comparer = comparer ?? Comparer<TKey>.Default;

        var grouped = source.GroupBy(keySelector);
        var ordered =
            descending
                ? grouped.OrderByDescending(g => g.Key, comparer)
                : grouped.OrderBy(g => g.Key, comparer);

        int rank = 1;
        foreach (var group in ordered)
        {
            foreach (var item in group)
            {
                yield return resultSelector(item, rank);
            }
            rank++;
        }
    }

    #endregion

RankBy
DenseRankBy
之间的区别在于
RankBy
创建了“间隙”(例如1,1,3,3,3,6…),而
DenseRankBy
没有(1,1,2,2,2,3…)

我修改了上述伟大的方法,以保持原始顺序。排序方法不应该改变元素的顺序,它们应该只对元素进行排序,并按照输入集合的原始顺序返回元素

private static IEnumerable<TResult> RankBy<TSource, TKey, TResult>(
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector,
    IComparer<TKey> comparer,
    bool descending,
    Func<TSource, int, TResult> resultSelector)
{
    var comp0 = comparer ?? Comparer<TKey>.Default;
    var comp = descending ? Comparer<TKey>.Create((x, y) => -comp0.Compare(x, y)) : comp0;

    var keys = source.Select(x => keySelector(x)).ToArray();
    var indexes = Enumerable.Range(0, keys.Length).ToArray();
    Array.Sort<TKey, int>(keys, indexes, comp);

    var groups = new int[keys.Length];
    int group = 0;
    int index = 0;
    for (int j = 1; j < keys.Length; ++j)
    {
        ++index;
        if (comp.Compare(keys[j], keys[j - 1]) != 0)
        {
            group += index;
            index = 0;
        }
        groups[indexes[j]] = group;
    }

    index = 0;
    foreach (var item in source)
    {
        yield return resultSelector(item, groups[index++] + 1);
    }
}


private static IEnumerable<TResult> DenseRankBy<TSource, TKey, TResult>(
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector,
    IComparer<TKey> comparer,
    bool descending,
    Func<TSource, int, TResult> resultSelector)
{
    var comp0 = comparer ?? Comparer<TKey>.Default;
    var comp = descending ? Comparer<TKey>.Create((x, y) => -comp0.Compare(x, y)) : comp0;

    var keys = source.Select(x => keySelector(x)).ToArray();
    var indexes = Enumerable.Range(0, keys.Length).ToArray();
    Array.Sort<TKey, int>(keys, indexes, comp);

    var groups = new int[keys.Length];
    int group = 0;
    for (int j = 1; j < keys.Length; ++j)
    {
        if (comp.Compare(keys[j], keys[j - 1]) != 0)
            ++group;
        groups[indexes[j]] = group;
    }

    int index = 0;
    foreach (var item in source)
    {
        yield return resultSelector(item, groups[index++] + 1);
    }
}
私有静态IEnumerable RankBy(
这是一个数不清的来源,
Func键选择器,
我的比较器,
布尔下降,
Func结果选择器)
{
var comp0=比较器??比较器默认值;
var comp=降序?比较器创建((x,y)=>-comp0.比较(x,y)):comp0;
var keys=source.Select(x=>keySelector(x)).ToArray();
var index=Enumerable.Range(0,keys.Length).ToArray();
排序(键、索引、comp);
变量组=新整数[keys.Length];
int组=0;
int指数=0;
对于(int j=1;j-comp0.比较(x,y)):comp0;
var keys=source.Select(x=>keySelector(x)).ToArray();
var index=Enumerable.Range(0,keys.Length).ToArray();
排序(键、索引、comp);
变量组=新整数[keys.Length];
int组=0;
对于(int j=1;j
为什么您的解决方案不好?LINQ可以大大简化一些查询,但有时使用循环的普通命令式代码会更好。LINQ并没有使循环过时。您可以发布您的解决方案,我们可以尝试使用LINQ简化(?!),但这并不总是有意义的。很少有好的解决方案为什么不实现
i可比较的
var rankedPlayers = players.RankByDescending(
                                p => p.Score,
                                (p, r) => new { Rank = r, Player = p });
private static IEnumerable<TResult> RankBy<TSource, TKey, TResult>(
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector,
    IComparer<TKey> comparer,
    bool descending,
    Func<TSource, int, TResult> resultSelector)
{
    var comp0 = comparer ?? Comparer<TKey>.Default;
    var comp = descending ? Comparer<TKey>.Create((x, y) => -comp0.Compare(x, y)) : comp0;

    var keys = source.Select(x => keySelector(x)).ToArray();
    var indexes = Enumerable.Range(0, keys.Length).ToArray();
    Array.Sort<TKey, int>(keys, indexes, comp);

    var groups = new int[keys.Length];
    int group = 0;
    int index = 0;
    for (int j = 1; j < keys.Length; ++j)
    {
        ++index;
        if (comp.Compare(keys[j], keys[j - 1]) != 0)
        {
            group += index;
            index = 0;
        }
        groups[indexes[j]] = group;
    }

    index = 0;
    foreach (var item in source)
    {
        yield return resultSelector(item, groups[index++] + 1);
    }
}


private static IEnumerable<TResult> DenseRankBy<TSource, TKey, TResult>(
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector,
    IComparer<TKey> comparer,
    bool descending,
    Func<TSource, int, TResult> resultSelector)
{
    var comp0 = comparer ?? Comparer<TKey>.Default;
    var comp = descending ? Comparer<TKey>.Create((x, y) => -comp0.Compare(x, y)) : comp0;

    var keys = source.Select(x => keySelector(x)).ToArray();
    var indexes = Enumerable.Range(0, keys.Length).ToArray();
    Array.Sort<TKey, int>(keys, indexes, comp);

    var groups = new int[keys.Length];
    int group = 0;
    for (int j = 1; j < keys.Length; ++j)
    {
        if (comp.Compare(keys[j], keys[j - 1]) != 0)
            ++group;
        groups[indexes[j]] = group;
    }

    int index = 0;
    foreach (var item in source)
    {
        yield return resultSelector(item, groups[index++] + 1);
    }
}