从不同的列表中获得优先级(按受欢迎程度)列表
本文关键字:列表 受欢迎 程度 优先级 | 更新日期: 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();