我正在努力获取一个 linq 语句,该语句为每个具有最大计数的玩家提供一条记录。
我的目标是显示 2 条记录: |玩家|标签 |计数 | | ------ | --- | -----| |玩家1 |橙色| 2 | |玩家2 |苹果| 1 |
我有一个查询 1,它似乎使标签变平。 然后通过查询 2,我为玩家和标签生成分组计数。
有没有办法只为每个玩家选择最上面的记录?
void Main()
{
Player p1 = new Player { Name = "Player1" };
Player p2 = new Player { Name = "Player2" };
List<PlayerAnswerRecord> UsedWords = new List<PlayerAnswerRecord>();
UsedWords.Insert(0, new PlayerAnswerRecord { Word = new DictionaryEntry{ Word = "fruit", Tags = new List<string>{"apple", "orange"} }, Player = p1, Score = 10, RecordType = AnserRecordType.Valid });
UsedWords.Insert(0, new PlayerAnswerRecord { Word = new DictionaryEntry{ Word = "fruit2", Tags = new List<string>{"pineapple", "orange"} }, Player = p1, Score = 10, RecordType = AnserRecordType.Valid });
UsedWords.Insert(0, new PlayerAnswerRecord { Word = new DictionaryEntry{ Word = "fruity", Tags = new List<string>{"apple", "orange"} }, Player = p2, Score = 25, RecordType = AnserRecordType.Valid });
foreach(var w in UsedWords)
{
//Console.WriteLine(w.Word.Word);
}
//UsedWords.GroupBy(
var grouped =
from entry in UsedWords
group entry by entry.Player into newGroup
select newGroup;
//Console.Write(grouped);
var query = UsedWords
.Select(x=> new {x.Player, x.Word})
.SelectMany(x=> x.Word.Tags);
var query1 = UsedWords.SelectMany (
c => c.Word.Tags,
(c, o) =>
new
{
Player = c.Player.Name,
Tag = o
}
);
//var query2 = query1.GroupBy(x=>x.Name).Select(group => new {Metric = group.Key, Count = group.Count()});
var query2 = query1.GroupBy(x=> new {x.Player, x.Tag}).Select(group => new {Player = group.Key.Player, Tag = group.Key.Tag, Count = group.Count()}).OrderByDescending(x=>x.Count);
//var query2 = query1.GroupBy(x=>x.Name).Select(group => group, (group, o) => new {Metric = group.Key, Count = group.Count()});
var query3 = query2.Max(x => x.Count);
Console.Write(query1);
Console.Write(query2);
Console.Write(query3);
}
// You can define other methods, fields, classes and namespaces here
public class PlayerAnswerRecord
{
public Player Player;
public DictionaryEntry Word;
public int Score;
public float ElapsedTime;
public AnserRecordType RecordType;
}
public enum AnserRecordType
{
Valid,
Invalid,
OutOfTime,
UsedWord
}
public class DictionaryEntry
{
public string Word;
public List<string> Tags;
}
public class Player
{
public string Name;
}
将查询分解为多个部分并没有什么问题。 LINQ 使用延迟执行(即查询在声明时不会执行,而是在迭代输出时执行),因此您可以将查询拆分为任意多个步骤,并且不会影响结果或性能。
但是如果您确实想编写一个查询,则可以使用以下内容:
var result =
from entry in UsedWords
from tags in entry.Word.Tags
group tags by entry.Player.Name
into tagsGroupedByPlayer
let mostFrequentTag = (from tags in tagsGroupedByPlayer
group tags by tags
into tags
select new { Tag = tags.Key, Count = tags.Count() } into tagAndCount
orderby tagAndCount.Count
select tagAndCount).First()
select new { Player = tagsGroupedByPlayer.Key, Tag = mostFrequentTag.Tag, Count = mostFrequentTag.Count };
显然,您可以自由修改最后的
select
子句,将结果投影为您想要的任何格式。