从不同的列表中获得优先级(按受欢迎程度)列表

本文关键字:列表 受欢迎 程度 优先级 | 更新日期: 2023-09-27 18:04:06

这个功能有点类似Stack Overflow徽章。

我有一个朋友列表,对于这些朋友,我可以通过以下方法获得他们所有的徽章:

GetBadgesFromUser (string用户)

我现在需要从我的朋友那里得到所有徽章的列表,按他们的受欢迎程度排序。

到目前为止,我有以下代码:
public List<string> GetRankedBadgeList()
{
    List<Tuple<string, int>> rankedBadgeList = new List<Tuple<string, int>>();
    List<string> friendList = new List<String>();
    List<string> badgesList = new List<string>();
    foreach (var friend in friendList)
    {
        var badges = GetBadgesFromUser(friend);
        if (badges == null || !badges.Any()) continue;
        rankedBadgeList = AddBadges(badges, rankedBadgeList);
    }
    return rankedBadgeList.Select(x => x.Item1).ToList();
}
private List<Tuple<string, int>> AddBadges(List<string> badges, List<Tuple<string, int>> rankedBadgeList)
{
    List<Tuple<string, int>> badgesRevisited = new List<Tuple<string, int>>();
    foreach (string badge in badges) 
    {
        foreach (var rankedBadge in rankedBadgeList)
        {
            if (rankedBadge.Item1 == badge)
                badgesRevisited.Add(new Tuple<string, int>(rankedBadge.Item1, rankedBadge.Item2 + 1));
            else
                badgesRevisited.Add(new Tuple<string, int>(badge, 0));
        }
    }
    return badgesRevisited;
}

我使用对象List<Tuple<string, int>>来获得没有重复的所有徽章,并使用int值来存储匹配的数量。我将遍历列表并根据其受欢迎程度(int值)对项目进行排序。

问题是,我不完全确定这是最好的方法,也许元组不是最好的工作。

从不同的列表中获得优先级(按受欢迎程度)列表

使用linq "one liner"可以很容易地做到这一点。

var orderedBadges = friendList
    .SelectMany(f=>GetBadgesFromUser(f))
    .GroupBy(b=>b)
    .Select(g=>new {Badge=g.Key, Count=g.Count()})
    .OrderByDescending(x=>x.Count)
    .Select(x=>x.Badge);

这样做是采取你的朋友列表,并将其转换为使用SelectMany的所有徽章的列表。

然后将它们分组,然后创建一个具有徽章名称的匿名对象,使用该对象上的计数对它们进行排序,然后仅为最终的IEnumerable<string>提取徽章名称。

我应该注意到,你可能不需要中间的匿名对象,但我包含它,因为它有助于清晰一点。

代替List<Tuple<string, int>>AddBadges的完整实现,您可以使用LINQ,它返回您需要的东西:

badges
   .GroupBy(p => p)
   .Select(group => new { Badge = group.Key, Count = group.Count()})
   .OrderByDescending(group => group.Count);

这将返回一个异常类型的IEnumerable,具有Badge属性(badges列表中的原始字符串,以及Count属性,按Count属性降序排列)。

所以你只需要像

这样的东西
foreach (var friend in friendList)
{
    var badges = GetBadgesFromUser(friend);
    if (badges == null || !badges.Any()) continue;
    rankedBadgeList.AddRange(<the LINQ statement above>);
}
return rankedBadgeList.Select(x => x.Badge).ToList();