Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Linq列表在C中的排名#_C#_Linq_Observablecollection - Fatal编程技术网

C# Linq列表在C中的排名#

C# Linq列表在C中的排名#,c#,linq,observablecollection,C#,Linq,Observablecollection,我有下面的名单,其中包括一个名单的名称和分数。我使用linq得到的分数是列表中所有人的分数之和: Name Score Ed 5 John 6 Sara 7 Dean 3 Nora 4 因此,我能够对列表进行分组并计算总数,但现在我正试图根据分数对这些列表进行排序。因此,我试图获得以下列表: Rank Name Score 1 Sara 7 2 John 6 3 Ed 5 4 Nora 4 5 Dean

我有下面的名单,其中包括一个名单的名称和分数。我使用linq得到的分数是列表中所有人的分数之和:

  Name  Score
   Ed    5
   John  6
   Sara  7
   Dean  3
   Nora  4
因此,我能够对列表进行分组并计算总数,但现在我正试图根据分数对这些列表进行排序。因此,我试图获得以下列表:

Rank Name Score
 1   Sara  7
 2   John  6
 3   Ed    5
 4   Nora  4
 5   Dean  3
但是我使用的linq代码似乎没有为我获得正确的排名

以下是我的代码,用于制作列表、求和和和排名:

    public class Person
    {

        public int Rank { get; set; }
        public string Name { get; private set; }
        public int Score { get; set; }

        public Person(int rank, string name, int score)
        {
            Rank = rank;
            Name = name;
            Score = score;

        }
    }

    public ObservableCollection<Person> Persons { get; set; }
    public MainWindow()
    {            
 Persons = new ObservableCollection<Person>();
        var data = lines.Select(line => {
        var column = line.Split(',');
        var name = column[0];
        int score = int.Parse(column[1]);
        int rank =0; 
        return new { name, score, rank };
    });

        var groupedData = data.OrderByDescending(x => x.score).GroupBy(p => p.name).Select((g, i) => new { name = g.Key, rank=i+1, score = g.Sum(p => p.score)});

    var persons = groupedData.Select(p => new Person(p.rank, p.name, p.score));

    foreach (var person in persons) {
        Persons.Add(person);
    }
    datagrid.ItemsSource = Persons;
}
公共类人物
{
公共整数秩{get;set;}
公共字符串名称{get;private set;}
公共整数分数{get;set;}
公众人物(整数排名、字符串名称、整数分数)
{
秩=秩;
名称=名称;
分数=分数;
}
}
公共可观察集合人员{get;set;}
公共主窗口()
{            
人员=新的可观察集合();
变量数据=行。选择(行=>{
var column=line.Split(',');
变量名称=列[0];
int score=int.Parse(列[1]);
int秩=0;
返回新的{name,score,rank};
});
var groupedData=data.OrderByDescending(x=>x.score).GroupBy(p=>p.name).Select((g,i)=>new{name=g.Key,rank=i+1,score=g.Sum(p=>p.score)});
变量persons=groupedData.Select(p=>newpersons(p.rank,p.name,p.score));
foreach(var个人对个人){
人。添加(人);
}
datagrid.ItemsSource=个人;
}

我只是想知道如何在linq中包含正确的等级。

您必须
按降序排列
分组数据(具有总分),而不是包含未求和的单个分数的原始数据

var persons = groupedData.Select(p => new Person(p.rank, p.name, p.score)).OrderByDescending(x => x.Score);
编辑:(将正确的排名放入
Person.rank


您必须按降序排列
groupedData
(具有总分),而不是包含未求和的单个分数的原始数据

var persons = groupedData.Select(p => new Person(p.rank, p.name, p.score)).OrderByDescending(x => x.Score);
编辑:(将正确的排名放入
Person.rank


不久前我问了一个类似的问题。我的问题是,如果人们有相同的分数,它将分配错误的排名的人。根据您当前的代码,如果John的分数也为7,他将被排在第2位,因为您按分数排序,并且仅使用其在列表中的位置,而他实际上与第1位并列


这是我的问题和解决方案:

不久前我问了一个类似的问题。我的问题是,如果人们有相同的分数,它将分配错误的排名的人。根据您当前的代码,如果John的分数也为7,他将被排在第2位,因为您按分数排序,并且仅使用其在列表中的位置,而他实际上与第1位并列


这是我的问题和解决方案:

一个扩展方法如何进行排名:

public static IEnumerable<TResult> SelectRank<TSource, TValue, TResult>(this IEnumerable<TSource> source, 
     Func<TSource, TValue> valueSelector, 
     Func<TSource, int, TResult> selector)
            where TValue : struct
        {
            TValue? previousValue = default(TValue?);
            var count = 0;
            var rank = 0;
            foreach (var item in source)
            {
                count++;
                var value = valueSelector(item);
                if (!value.Equals(previousValue))
                {
                    rank = count;
                    previousValue = value;
                }
                yield return selector(item, rank);
            }
        }
公共静态IEnumerable SelectRank(此IEnumerable源,
Func值选择器,
Func选择器)
其中TValue:struct
{
TValue?previousValue=默认值(TValue?);
var计数=0;
var秩=0;
foreach(源中的var项)
{
计数++;
var值=值选择器(项目);
如果(!value.Equals(previousValue))
{
排名=计数;
前一个值=值;
}
收益率返回选择器(项目、等级);
}
}

用法
profiles.SelectRank(x=>x.Score,(x,r)=>new{x.Name,Rank=r})
。此方法只对源代码执行1次迭代。我确实建议使用排序的
参数。

扩展方法如何进行排序:

public static IEnumerable<TResult> SelectRank<TSource, TValue, TResult>(this IEnumerable<TSource> source, 
     Func<TSource, TValue> valueSelector, 
     Func<TSource, int, TResult> selector)
            where TValue : struct
        {
            TValue? previousValue = default(TValue?);
            var count = 0;
            var rank = 0;
            foreach (var item in source)
            {
                count++;
                var value = valueSelector(item);
                if (!value.Equals(previousValue))
                {
                    rank = count;
                    previousValue = value;
                }
                yield return selector(item, rank);
            }
        }
公共静态IEnumerable SelectRank(此IEnumerable源,
Func值选择器,
Func选择器)
其中TValue:struct
{
TValue?previousValue=默认值(TValue?);
var计数=0;
var秩=0;
foreach(源中的var项)
{
计数++;
var值=值选择器(项目);
如果(!value.Equals(previousValue))
{
排名=计数;
前一个值=值;
}
收益率返回选择器(项目、等级);
}
}

用法
profiles.SelectRank(x=>x.Score,(x,r)=>new{x.Name,Rank=r})
。此方法只对源代码执行1次迭代。我建议使用排序的
参数。

在此处添加代码以供完成,例如:

var entriesByPoints = tournament.Entries.GroupBy(g=>g.Picks.Sum(s=>s.TournamentContestant.TotalScoreTargetAllocatedPoints)).Select((group)=> new { 
            Points = group.Key,
            Entries = group.ToList()
            });

var entriesByRankWithPoints = entriesByPoints.OrderByDescending(ob=>ob.Points).Select((p,i) => new {
            Rank = 1 + (entriesByPoints.Where(w=>w.Points > p.Points).Sum(s=>s.Entries.Count())), 
            Points = p.Points, 
            Entries = p.Entries
        });
结果:


在此处添加代码以完成比赛示例:

var entriesByPoints = tournament.Entries.GroupBy(g=>g.Picks.Sum(s=>s.TournamentContestant.TotalScoreTargetAllocatedPoints)).Select((group)=> new { 
            Points = group.Key,
            Entries = group.ToList()
            });

var entriesByRankWithPoints = entriesByPoints.OrderByDescending(ob=>ob.Points).Select((p,i) => new {
            Rank = 1 + (entriesByPoints.Where(w=>w.Points > p.Points).Sum(s=>s.Entries.Count())), 
            Points = p.Points, 
            Entries = p.Entries
        });
结果:


您好,谢谢您的回复。我尝试了你提出的解决方案,但仍然没有得到正确的排名:排名编码在列表位置,我将更新答案,在
Person.rank
Perfect中提供它!现在我需要弄清楚如何为那些得分相同的人确定排名。非常感谢:)我会按分数分组,按分数排序,然后根据每个GroupGreeting中的元素数进行聚合来创建排名。谢谢你的回复。我尝试了你提出的解决方案,但仍然没有得到正确的排名:排名编码在列表位置,我将更新答案,在
Person.rank
Perfect中提供它!现在我需要弄清楚如何为那些得分相同的人确定排名。非常感谢:)我会按分数分组,按分数排序,然后通过每个组中元素的计数进行聚合来创建排名谢谢您的回复。您能解释一下解决方案吗?因为我不明白它的实现是如何解决这个问题的:)谢谢您的回复。您能解释一下解决方案吗,因为我不明白它的实现是如何解决这个问题的:)