此功能有点类似于Stack Overflow徽章。
我有一个朋友列表,对于这些朋友,我可以使用该方法获得所有徽章:
GetBadgesFromUser(string user)
我现在需要从朋友那里得到所有徽章的清单,按其受欢迎程度排序。
到目前为止,我有以下代码:
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
值)来订购项目。
问题是我不完全确定这是最好的方法,也许元组不是最好的工作。
答案 0 :(得分:4)
您可以使用linq&#34;一个衬垫&#34;很容易。
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>
的徽章名称。
我应该注意到你可能不需要中间的匿名对象,但我把它包括在内,因为它有助于提高清晰度。
答案 1 :(得分:2)
而不是List<Tuple<string, int>>
和AddBadges
的完整实现,您可以使用LINQ,它返回您需要的内容:
badges
.GroupBy(p => p)
.Select(group => new { Badge = group.Key, Count = group.Count()})
.OrderByDescending(group => group.Count);
这将返回一个IEnumerable
的anomyous类型,其Badge
属性(badges
列表中的原始字符串和Count
属性,由{命令{1}}属性(降序)。
所以你只需要像
这样的东西Count