逐个元素选择最重复的项目

时间:2017-01-31 09:13:56

标签: c# algorithm linq logic

我正在尝试获得与主要文章相同的大多数标签的3篇相关文章。 我有这个DB结构:

StructDB

当我收到主要文章时,我会得到与文章相关的标签。然后,我将文章的IDArticle和TagList传递给函数,以获取相关的3篇文章 作为文章和标签之间粘合剂的列表是ArticoloTag,我认为这是要检查的列表,以获得具有大多数重复标签的文章。
显然我觉得用c#在服务器端开发这个算法会更好。如何用linq做到这一点?
谢谢你的帮助

4 个答案:

答案 0 :(得分:1)

为了找到共享最多标签的前3篇文章,您可以使用ArticoloTag并加入IdTag

linq看起来像这样:

ArticoloTag.Where (a=>a.IdArticolo== mainArticleId).Join(ArticoloTag, a=>a.IdTag, a=>a.IdTag, (a,b)=> b.IdArticolo).GroupBy(a=>a.IdArticolo).OrderBy(g=>g.Count()).Select(g => g.Key).Take(3)

这将取回您的3 IdArticle。

您可以向Articolo表添加联接以获取实际文章

答案 1 :(得分:1)

我可能会误解您的问题但是当您想从共享关系表的表中获取数据时,您需要从最低表开始并在分组中进行备份。 您将不得不在此处执行您的数据库代码,因为我不知道您将使用什么。这不是实际的编译代码,而是指导代码:

var list = dbConext.Tag.Where([your filter]).SelectMany( i => i.ArticoloTags).GroupBy(i => i.IDTag).OrderBy(i=>i.Count()).ToList();

从这个列表中你可以做你想做的事。

答案 2 :(得分:1)

不确定这是否效率低,但你可以尝试这样的事情(searchTagList是给定文章的标签列表)

var relavantList = articleList.
            Select(a => new {
                artical = a,
                relevancyCount = a.ArticoloTag.Where(tag => searchTagList.Contains(tag)).Count()
            }).
            ToList().
            OrderByDescending(a => a.relevancyCount).
            ThenBy(a => a.artical.Title). //if similar relevancy then ordered by title
            Take(3).ToList();

以下是我使用的数据结构。

class Articolo {

    public int ID { get; set; }

    public List<Tag> ArticoloTag { get; set; }

    public string Title { get; set; }

}

class Tag {

    public int ID { get; set; }

    public string TagText { get; set; }
}

答案 3 :(得分:0)

这样做的一种方法可能是:

  1. 从主文章中提取标签
  2. 使用该标记查找其他文章
  3. 为找到的文章保留字典,并为每个匹配的标记增加一个计数器
  4. 订购字典并获得前3个结果

    static void Main(string[] args)
    {
        var articleTags = new List<ArticleTag>
        {
            new ArticleTag(1, "a"),
            new ArticleTag(1, "b"),
            new ArticleTag(1, "c"),
            new ArticleTag(2, "a"),
            new ArticleTag(2, "b"),
            new ArticleTag(3, "a"),
            new ArticleTag(4, "b"),
            new ArticleTag(4, "c"),
            new ArticleTag(5, "a"),
            new ArticleTag(5, "b"),
            new ArticleTag(5, "c"),
        };
    
        var resultDict = new Dictionary<int, int>(); // Where we store the result
        const int mainArticleId = 1; // Your main article
        var tagsFromMainArticle = articleTags.Where(x => x.Id == mainArticleId).Select(x => x.Tag).ToList(); // All tags on the main article
    
        tagsFromMainArticle.ForEach(tag => 
            articleTags
                .Where(a => a.Tag == tag && a.Id != mainArticleId)
                .ToList()
                .ForEach(x =>
                {
                    if (resultDict.ContainsKey(x.Id)) resultDict[x.Id]++;
                    else resultDict[x.Id] = 1;
                }));
    
        foreach (var resultKeyValuePair in resultDict.OrderByDescending(v => v.Value).Take(3))
        {
            Console.WriteLine($"Key = {resultKeyValuePair.Key}, Value = {resultKeyValuePair.Value}");
        }
    }
    
  5. 以下是示例

    的简单ArticleTag类
    public class ArticleTag
    {
        public ArticleTag(int id, string tag)
        {
           Id = id;
           Tag = tag;
        }
    
        public int Id { get; private set; }
        public string Tag { get; private set; }
    }