如何使用LINQ进行分组和选择顶部记录?

x33g5p2x  于 7个月前  发布在  其他
关注(0)|答案(1)|浏览(83)

我正在努力得到一个linq声明,给我一个单一的记录,为每个球员与最大的计数。
我的目标是显示2条记录:
| 球员|标签|计数|
| --|--|--|
| 播放器1|橙子| 2 |
| Player2|苹果| 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;
}

字符串

a14dhokn

a14dhokn1#

将查询分解成多个部分并没有什么错。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子句,将结果投影为您希望的任何格式。

相关问题