从不同列表

时间:2015-07-23 08:14:04

标签: c# algorithm list tuples

此功能有点类似于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值)来订购项目。

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

2 个答案:

答案 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